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
00035
00036
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
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
00077
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 ||
00099 oid.oid[1] != 2 ||
00100 oid.oid[2] != 840 ||
00101 oid.oid[3] != 113549 ||
00102 oid.oid[4] != 1 ||
00103 oid.oid[5] != 1 ||
00104 oid.oid[6] != 1 ) {
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
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
00142
00143
00144
00145
00146
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
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
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