diff options
Diffstat (limited to 'src/lib/libcrypto/pkcs12/p12_kiss.c')
| -rw-r--r-- | src/lib/libcrypto/pkcs12/p12_kiss.c | 100 |
1 files changed, 65 insertions, 35 deletions
diff --git a/src/lib/libcrypto/pkcs12/p12_kiss.c b/src/lib/libcrypto/pkcs12/p12_kiss.c index ee257ffbad..1fbbd6c99f 100644 --- a/src/lib/libcrypto/pkcs12/p12_kiss.c +++ b/src/lib/libcrypto/pkcs12/p12_kiss.c | |||
| @@ -65,9 +65,10 @@ | |||
| 65 | static int parse_pk12( PKCS12 *p12, const char *pass, int passlen, | 65 | static int parse_pk12( PKCS12 *p12, const char *pass, int passlen, |
| 66 | EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca); | 66 | EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca); |
| 67 | 67 | ||
| 68 | static int parse_bags( STACK *bags, const char *pass, int passlen, | 68 | static int parse_bags( STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass, |
| 69 | EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca, | 69 | int passlen, EVP_PKEY **pkey, X509 **cert, |
| 70 | ASN1_OCTET_STRING **keyid, char *keymatch); | 70 | STACK_OF(X509) **ca, ASN1_OCTET_STRING **keyid, |
| 71 | char *keymatch); | ||
| 71 | 72 | ||
| 72 | static int parse_bag( PKCS12_SAFEBAG *bag, const char *pass, int passlen, | 73 | static int parse_bag( PKCS12_SAFEBAG *bag, const char *pass, int passlen, |
| 73 | EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca, | 74 | EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca, |
| @@ -85,32 +86,41 @@ int PKCS12_parse (PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, | |||
| 85 | 86 | ||
| 86 | /* Check for NULL PKCS12 structure */ | 87 | /* Check for NULL PKCS12 structure */ |
| 87 | 88 | ||
| 88 | if(!p12) | 89 | if(!p12) { |
| 89 | { | ||
| 90 | PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_INVALID_NULL_PKCS12_POINTER); | 90 | PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_INVALID_NULL_PKCS12_POINTER); |
| 91 | return 0; | 91 | return 0; |
| 92 | } | 92 | } |
| 93 | 93 | ||
| 94 | /* Allocate stack for ca certificates if needed */ | 94 | /* Allocate stack for ca certificates if needed */ |
| 95 | if ((ca != NULL) && (*ca == NULL)) | 95 | if ((ca != NULL) && (*ca == NULL)) { |
| 96 | { | 96 | if (!(*ca = sk_X509_new_null())) { |
| 97 | if (!(*ca = sk_X509_new(NULL))) | ||
| 98 | { | ||
| 99 | PKCS12err(PKCS12_F_PKCS12_PARSE,ERR_R_MALLOC_FAILURE); | 97 | PKCS12err(PKCS12_F_PKCS12_PARSE,ERR_R_MALLOC_FAILURE); |
| 100 | return 0; | 98 | return 0; |
| 101 | } | ||
| 102 | } | 99 | } |
| 100 | } | ||
| 103 | 101 | ||
| 104 | if(pkey) *pkey = NULL; | 102 | if(pkey) *pkey = NULL; |
| 105 | if(cert) *cert = NULL; | 103 | if(cert) *cert = NULL; |
| 106 | 104 | ||
| 107 | /* Check the mac */ | 105 | /* Check the mac */ |
| 108 | 106 | ||
| 109 | if (!PKCS12_verify_mac (p12, pass, -1)) | 107 | /* If password is zero length or NULL then try verifying both cases |
| 110 | { | 108 | * to determine which password is correct. The reason for this is that |
| 109 | * under PKCS#12 password based encryption no password and a zero length | ||
| 110 | * password are two different things... | ||
| 111 | */ | ||
| 112 | |||
| 113 | if(!pass || !*pass) { | ||
| 114 | if(PKCS12_verify_mac(p12, NULL, 0)) pass = NULL; | ||
| 115 | else if(PKCS12_verify_mac(p12, "", 0)) pass = ""; | ||
| 116 | else { | ||
| 117 | PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_MAC_VERIFY_FAILURE); | ||
| 118 | goto err; | ||
| 119 | } | ||
| 120 | } else if (!PKCS12_verify_mac(p12, pass, -1)) { | ||
| 111 | PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_MAC_VERIFY_FAILURE); | 121 | PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_MAC_VERIFY_FAILURE); |
| 112 | goto err; | 122 | goto err; |
| 113 | } | 123 | } |
| 114 | 124 | ||
| 115 | if (!parse_pk12 (p12, pass, -1, pkey, cert, ca)) | 125 | if (!parse_pk12 (p12, pass, -1, pkey, cert, ca)) |
| 116 | { | 126 | { |
| @@ -122,9 +132,9 @@ int PKCS12_parse (PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, | |||
| 122 | 132 | ||
| 123 | err: | 133 | err: |
| 124 | 134 | ||
| 125 | if (pkey && *pkey) EVP_PKEY_free (*pkey); | 135 | if (pkey && *pkey) EVP_PKEY_free(*pkey); |
| 126 | if (cert && *cert) X509_free (*cert); | 136 | if (cert && *cert) X509_free(*cert); |
| 127 | if (ca) sk_X509_pop_free (*ca, X509_free); | 137 | if (ca) sk_X509_pop_free(*ca, X509_free); |
| 128 | return 0; | 138 | return 0; |
| 129 | 139 | ||
| 130 | } | 140 | } |
| @@ -134,45 +144,48 @@ int PKCS12_parse (PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, | |||
| 134 | static int parse_pk12 (PKCS12 *p12, const char *pass, int passlen, | 144 | static int parse_pk12 (PKCS12 *p12, const char *pass, int passlen, |
| 135 | EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca) | 145 | EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca) |
| 136 | { | 146 | { |
| 137 | STACK *asafes, *bags; | 147 | STACK_OF(PKCS7) *asafes; |
| 148 | STACK_OF(PKCS12_SAFEBAG) *bags; | ||
| 138 | int i, bagnid; | 149 | int i, bagnid; |
| 139 | PKCS7 *p7; | 150 | PKCS7 *p7; |
| 140 | ASN1_OCTET_STRING *keyid = NULL; | 151 | ASN1_OCTET_STRING *keyid = NULL; |
| 152 | |||
| 141 | char keymatch = 0; | 153 | char keymatch = 0; |
| 142 | if (!( asafes = M_PKCS12_unpack_authsafes (p12))) return 0; | 154 | if (!( asafes = M_PKCS12_unpack_authsafes (p12))) return 0; |
| 143 | for (i = 0; i < sk_num (asafes); i++) { | 155 | for (i = 0; i < sk_PKCS7_num (asafes); i++) { |
| 144 | p7 = (PKCS7 *) sk_value (asafes, i); | 156 | p7 = sk_PKCS7_value (asafes, i); |
| 145 | bagnid = OBJ_obj2nid (p7->type); | 157 | bagnid = OBJ_obj2nid (p7->type); |
| 146 | if (bagnid == NID_pkcs7_data) { | 158 | if (bagnid == NID_pkcs7_data) { |
| 147 | bags = M_PKCS12_unpack_p7data (p7); | 159 | bags = M_PKCS12_unpack_p7data(p7); |
| 148 | } else if (bagnid == NID_pkcs7_encrypted) { | 160 | } else if (bagnid == NID_pkcs7_encrypted) { |
| 149 | bags = M_PKCS12_unpack_p7encdata (p7, pass, passlen); | 161 | bags = M_PKCS12_unpack_p7encdata(p7, pass, passlen); |
| 150 | } else continue; | 162 | } else continue; |
| 151 | if (!bags) { | 163 | if (!bags) { |
| 152 | sk_pop_free (asafes, PKCS7_free); | 164 | sk_PKCS7_pop_free(asafes, PKCS7_free); |
| 153 | return 0; | 165 | return 0; |
| 154 | } | 166 | } |
| 155 | if (!parse_bags(bags, pass, passlen, pkey, cert, ca, | 167 | if (!parse_bags(bags, pass, passlen, pkey, cert, ca, |
| 156 | &keyid, &keymatch)) { | 168 | &keyid, &keymatch)) { |
| 157 | sk_pop_free(bags, PKCS12_SAFEBAG_free); | 169 | sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); |
| 158 | sk_pop_free(asafes, PKCS7_free); | 170 | sk_PKCS7_pop_free(asafes, PKCS7_free); |
| 159 | return 0; | 171 | return 0; |
| 160 | } | 172 | } |
| 161 | sk_pop_free(bags, PKCS12_SAFEBAG_free); | 173 | sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); |
| 162 | } | 174 | } |
| 163 | sk_pop_free(asafes, PKCS7_free); | 175 | sk_PKCS7_pop_free(asafes, PKCS7_free); |
| 164 | if (keyid) M_ASN1_OCTET_STRING_free(keyid); | 176 | if (keyid) M_ASN1_OCTET_STRING_free(keyid); |
| 165 | return 1; | 177 | return 1; |
| 166 | } | 178 | } |
| 167 | 179 | ||
| 168 | 180 | ||
| 169 | static int parse_bags (STACK *bags, const char *pass, int passlen, | 181 | static int parse_bags (STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass, |
| 170 | EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca, | 182 | int passlen, EVP_PKEY **pkey, X509 **cert, |
| 171 | ASN1_OCTET_STRING **keyid, char *keymatch) | 183 | STACK_OF(X509) **ca, ASN1_OCTET_STRING **keyid, |
| 184 | char *keymatch) | ||
| 172 | { | 185 | { |
| 173 | int i; | 186 | int i; |
| 174 | for (i = 0; i < sk_num(bags); i++) { | 187 | for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) { |
| 175 | if (!parse_bag((PKCS12_SAFEBAG *)sk_value (bags, i), | 188 | if (!parse_bag(sk_PKCS12_SAFEBAG_value (bags, i), |
| 176 | pass, passlen, pkey, cert, ca, keyid, | 189 | pass, passlen, pkey, cert, ca, keyid, |
| 177 | keymatch)) return 0; | 190 | keymatch)) return 0; |
| 178 | } | 191 | } |
| @@ -190,12 +203,17 @@ static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, | |||
| 190 | { | 203 | { |
| 191 | PKCS8_PRIV_KEY_INFO *p8; | 204 | PKCS8_PRIV_KEY_INFO *p8; |
| 192 | X509 *x509; | 205 | X509 *x509; |
| 193 | ASN1_OCTET_STRING *lkey = NULL; | 206 | ASN1_OCTET_STRING *lkey = NULL, *ckid = NULL; |
| 194 | ASN1_TYPE *attrib; | 207 | ASN1_TYPE *attrib; |
| 208 | ASN1_BMPSTRING *fname = NULL; | ||
| 195 | 209 | ||
| 210 | if ((attrib = PKCS12_get_attr (bag, NID_friendlyName))) | ||
| 211 | fname = attrib->value.bmpstring; | ||
| 196 | 212 | ||
| 197 | if ((attrib = PKCS12_get_attr (bag, NID_localKeyID))) | 213 | if ((attrib = PKCS12_get_attr (bag, NID_localKeyID))) { |
| 198 | lkey = attrib->value.octet_string; | 214 | lkey = attrib->value.octet_string; |
| 215 | ckid = lkey; | ||
| 216 | } | ||
| 199 | 217 | ||
| 200 | /* Check for any local key id matching (if needed) */ | 218 | /* Check for any local key id matching (if needed) */ |
| 201 | if (lkey && ((*keymatch & MATCH_ALL) != MATCH_ALL)) { | 219 | if (lkey && ((*keymatch & MATCH_ALL) != MATCH_ALL)) { |
| @@ -231,6 +249,18 @@ static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, | |||
| 231 | if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate ) | 249 | if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate ) |
| 232 | return 1; | 250 | return 1; |
| 233 | if (!(x509 = M_PKCS12_certbag2x509(bag))) return 0; | 251 | if (!(x509 = M_PKCS12_certbag2x509(bag))) return 0; |
| 252 | if(ckid) X509_keyid_set1(x509, ckid->data, ckid->length); | ||
| 253 | if(fname) { | ||
| 254 | int len; | ||
| 255 | unsigned char *data; | ||
| 256 | len = ASN1_STRING_to_UTF8(&data, fname); | ||
| 257 | if(len > 0) { | ||
| 258 | X509_alias_set1(x509, data, len); | ||
| 259 | OPENSSL_free(data); | ||
| 260 | } | ||
| 261 | } | ||
| 262 | |||
| 263 | |||
| 234 | if (lkey) { | 264 | if (lkey) { |
| 235 | *keymatch |= MATCH_CERT; | 265 | *keymatch |= MATCH_CERT; |
| 236 | if (cert) *cert = x509; | 266 | if (cert) *cert = x509; |
