00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
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
00034
00035
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
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
00076
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 ||
00098 oid.oid[1] != 2 ||
00099 oid.oid[2] != 840 ||
00100 oid.oid[3] != 113549 ||
00101 oid.oid[4] != 1 ||
00102 oid.oid[5] != 1 ||
00103 oid.oid[6] != 1 ) {
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
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
00141
00142
00143
00144
00145
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
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
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 }