pkcs8.c

Go to the documentation of this file.
00001 
00016 #include "includes.h"
00017 
00018 #include "common.h"
00019 #include "asn1.h"
00020 #include "bignum.h"
00021 #include "rsa.h"
00022 #include "pkcs5.h"
00023 #include "pkcs8.h"
00024 
00025 
00026 struct crypto_private_key * pkcs8_key_import(const u8 *buf, size_t len)
00027 {
00028         struct asn1_hdr hdr;
00029         const u8 *pos, *end;
00030         struct bignum *zero;
00031         struct asn1_oid oid;
00032         char obuf[80];
00033 
00034         /* PKCS #8, Chapter 6 */
00035 
00036         /* PrivateKeyInfo ::= SEQUENCE */
00037         if (asn1_get_next(buf, len, &hdr) < 0 ||
00038             hdr.class != ASN1_CLASS_UNIVERSAL ||
00039             hdr.tag != ASN1_TAG_SEQUENCE) {
00040                 wpa_printf(MSG_DEBUG, "PKCS #8: Does not start with PKCS #8 "
00041                            "header (SEQUENCE); assume PKCS #8 not used");
00042                 return NULL;
00043         }
00044         pos = hdr.payload;
00045         end = pos + hdr.length;
00046 
00047         /* version Version (Version ::= INTEGER) */
00048         if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
00049             hdr.class != ASN1_CLASS_UNIVERSAL || hdr.tag != ASN1_TAG_INTEGER) {
00050                 wpa_printf(MSG_DEBUG, "PKCS #8: Expected INTEGER - found "
00051                            "class %d tag 0x%x; assume PKCS #8 not used",
00052                            hdr.class, hdr.tag);
00053                 return NULL;
00054         }
00055 
00056         zero = bignum_init();
00057         if (zero == NULL)
00058                 return NULL;
00059 
00060         if (bignum_set_unsigned_bin(zero, hdr.payload, hdr.length) < 0) {
00061                 wpa_printf(MSG_DEBUG, "PKCS #8: Failed to parse INTEGER");
00062                 bignum_deinit(zero);
00063                 return NULL;
00064         }
00065         pos = hdr.payload + hdr.length;
00066 
00067         if (bignum_cmp_d(zero, 0) != 0) {
00068                 wpa_printf(MSG_DEBUG, "PKCS #8: Expected zero INTEGER in the "
00069                            "beginning of private key; not found; assume "
00070                            "PKCS #8 not used");
00071                 bignum_deinit(zero);
00072                 return NULL;
00073         }
00074         bignum_deinit(zero);
00075 
00076         /* privateKeyAlgorithm PrivateKeyAlgorithmIdentifier
00077          * (PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier) */
00078         if (asn1_get_next(pos, len, &hdr) < 0 ||
00079             hdr.class != ASN1_CLASS_UNIVERSAL ||
00080             hdr.tag != ASN1_TAG_SEQUENCE) {
00081                 wpa_printf(MSG_DEBUG, "PKCS #8: Expected SEQUENCE "
00082                            "(AlgorithmIdentifier) - found class %d tag 0x%x; "
00083                            "assume PKCS #8 not used",
00084                            hdr.class, hdr.tag);
00085                 return NULL;
00086         }
00087 
00088         if (asn1_get_oid(hdr.payload, hdr.length, &oid, &pos)) {
00089                 wpa_printf(MSG_DEBUG, "PKCS #8: Failed to parse OID "
00090                            "(algorithm); assume PKCS #8 not used");
00091                 return NULL;
00092         }
00093 
00094         asn1_oid_to_str(&oid, obuf, sizeof(obuf));
00095         wpa_printf(MSG_DEBUG, "PKCS #8: algorithm=%s", obuf);
00096 
00097         if (oid.len != 7 ||
00098             oid.oid[0] != 1 /* iso */ ||
00099             oid.oid[1] != 2 /* member-body */ ||
00100             oid.oid[2] != 840 /* us */ ||
00101             oid.oid[3] != 113549 /* rsadsi */ ||
00102             oid.oid[4] != 1 /* pkcs */ ||
00103             oid.oid[5] != 1 /* pkcs-1 */ ||
00104             oid.oid[6] != 1 /* rsaEncryption */) {
00105                 wpa_printf(MSG_DEBUG, "PKCS #8: Unsupported private key "
00106                            "algorithm %s", obuf);
00107                 return NULL;
00108         }
00109 
00110         pos = hdr.payload + hdr.length;
00111 
00112         /* privateKey PrivateKey (PrivateKey ::= OCTET STRING) */
00113         if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
00114             hdr.class != ASN1_CLASS_UNIVERSAL ||
00115             hdr.tag != ASN1_TAG_OCTETSTRING) {
00116                 wpa_printf(MSG_DEBUG, "PKCS #8: Expected OCTETSTRING "
00117                            "(privateKey) - found class %d tag 0x%x",
00118                            hdr.class, hdr.tag);
00119                 return NULL;
00120         }
00121         wpa_printf(MSG_DEBUG, "PKCS #8: Try to parse RSAPrivateKey");
00122 
00123         return (struct crypto_private_key *)
00124                 crypto_rsa_import_private_key(hdr.payload, hdr.length);
00125 }
00126 
00127 
00128 struct crypto_private_key *
00129 pkcs8_enc_key_import(const u8 *buf, size_t len, const char *passwd)
00130 {
00131         struct asn1_hdr hdr;
00132         const u8 *pos, *end, *enc_alg;
00133         size_t enc_alg_len;
00134         u8 *data;
00135         size_t data_len;
00136 
00137         if (passwd == NULL)
00138                 return NULL;
00139 
00140         /*
00141          * PKCS #8, Chapter 7
00142          * EncryptedPrivateKeyInfo ::= SEQUENCE {
00143          *   encryptionAlgorithm EncryptionAlgorithmIdentifier,
00144          *   encryptedData EncryptedData }
00145          * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
00146          * EncryptedData ::= OCTET STRING
00147          */
00148 
00149         if (asn1_get_next(buf, len, &hdr) < 0 ||
00150             hdr.class != ASN1_CLASS_UNIVERSAL ||
00151             hdr.tag != ASN1_TAG_SEQUENCE) {
00152                 wpa_printf(MSG_DEBUG, "PKCS #8: Does not start with PKCS #8 "
00153                            "header (SEQUENCE); assume encrypted PKCS #8 not "
00154                            "used");
00155                 return NULL;
00156         }
00157         pos = hdr.payload;
00158         end = pos + hdr.length;
00159 
00160         /* encryptionAlgorithm EncryptionAlgorithmIdentifier */
00161         if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
00162             hdr.class != ASN1_CLASS_UNIVERSAL ||
00163             hdr.tag != ASN1_TAG_SEQUENCE) {
00164                 wpa_printf(MSG_DEBUG, "PKCS #8: Expected SEQUENCE "
00165                            "(AlgorithmIdentifier) - found class %d tag 0x%x; "
00166                            "assume encrypted PKCS #8 not used",
00167                            hdr.class, hdr.tag);
00168                 return NULL;
00169         }
00170         enc_alg = hdr.payload;
00171         enc_alg_len = hdr.length;
00172         pos = hdr.payload + hdr.length;
00173 
00174         /* encryptedData EncryptedData */
00175         if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
00176             hdr.class != ASN1_CLASS_UNIVERSAL ||
00177             hdr.tag != ASN1_TAG_OCTETSTRING) {
00178                 wpa_printf(MSG_DEBUG, "PKCS #8: Expected OCTETSTRING "
00179                            "(encryptedData) - found class %d tag 0x%x",
00180                            hdr.class, hdr.tag);
00181                 return NULL;
00182         }
00183 
00184         data = pkcs5_decrypt(enc_alg, enc_alg_len, hdr.payload, hdr.length,
00185                              passwd, &data_len);
00186         if (data) {
00187                 struct crypto_private_key *key;
00188                 key = pkcs8_key_import(data, data_len);
00189                 os_free(data);
00190                 return key;
00191         }
00192 
00193         return NULL;
00194 }
00195 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines

Generated on Sat Nov 21 23:16:53 2009 for hostapd by  doxygen 1.6.1