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


wpa_supplicant
Author(s): Package maintained by Blaise Gassend
autogenerated on Thu Jan 2 2014 11:26:38