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; |