1 /* p12_kiss.c */ 2 /* Written by Dr Stephen N Henson (steve (at) openssl.org) for the OpenSSL 3 * project 1999. 4 */ 5 /* ==================================================================== 6 * Copyright (c) 1999 The OpenSSL Project. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 20 * 3. All advertising materials mentioning features or use of this 21 * software must display the following acknowledgment: 22 * "This product includes software developed by the OpenSSL Project 23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24 * 25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26 * endorse or promote products derived from this software without 27 * prior written permission. For written permission, please contact 28 * licensing (at) OpenSSL.org. 29 * 30 * 5. Products derived from this software may not be called "OpenSSL" 31 * nor may "OpenSSL" appear in their names without prior written 32 * permission of the OpenSSL Project. 33 * 34 * 6. Redistributions of any form whatsoever must retain the following 35 * acknowledgment: 36 * "This product includes software developed by the OpenSSL Project 37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38 * 39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50 * OF THE POSSIBILITY OF SUCH DAMAGE. 51 * ==================================================================== 52 * 53 * This product includes cryptographic software written by Eric Young 54 * (eay (at) cryptsoft.com). This product includes software written by Tim 55 * Hudson (tjh (at) cryptsoft.com). 56 * 57 */ 58 59 #include <stdio.h> 60 #include "cryptlib.h" 61 #include <openssl/pkcs12.h> 62 63 /* Simplified PKCS#12 routines */ 64 65 static int parse_pk12( PKCS12 *p12, const char *pass, int passlen, 66 EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca); 67 68 static int parse_bags( STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass, 69 int passlen, EVP_PKEY **pkey, X509 **cert, 70 STACK_OF(X509) **ca, ASN1_OCTET_STRING **keyid, 71 char *keymatch); 72 73 static int parse_bag( PKCS12_SAFEBAG *bag, const char *pass, int passlen, 74 EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca, 75 ASN1_OCTET_STRING **keyid, char *keymatch); 76 77 /* Parse and decrypt a PKCS#12 structure returning user key, user cert 78 * and other (CA) certs. Note either ca should be NULL, *ca should be NULL, 79 * or it should point to a valid STACK structure. pkey and cert can be 80 * passed unitialised. 81 */ 82 83 int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, 84 STACK_OF(X509) **ca) 85 { 86 87 /* Check for NULL PKCS12 structure */ 88 89 if(!p12) { 90 PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_INVALID_NULL_PKCS12_POINTER); 91 return 0; 92 } 93 94 /* Allocate stack for ca certificates if needed */ 95 if ((ca != NULL) && (*ca == NULL)) { 96 if (!(*ca = sk_X509_new_null())) { 97 PKCS12err(PKCS12_F_PKCS12_PARSE,ERR_R_MALLOC_FAILURE); 98 return 0; 99 } 100 } 101 102 if(pkey) *pkey = NULL; 103 if(cert) *cert = NULL; 104 105 /* Check the mac */ 106 107 /* If password is zero length or NULL then try verifying both cases 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)) { 121 PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_MAC_VERIFY_FAILURE); 122 goto err; 123 } 124 125 if (!parse_pk12 (p12, pass, -1, pkey, cert, ca)) 126 { 127 PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_PARSE_ERROR); 128 goto err; 129 } 130 131 return 1; 132 133 err: 134 135 if (pkey && *pkey) EVP_PKEY_free(*pkey); 136 if (cert && *cert) X509_free(*cert); 137 if (ca) sk_X509_pop_free(*ca, X509_free); 138 return 0; 139 140 } 141 142 /* Parse the outer PKCS#12 structure */ 143 144 static int parse_pk12(PKCS12 *p12, const char *pass, int passlen, 145 EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca) 146 { 147 STACK_OF(PKCS7) *asafes; 148 STACK_OF(PKCS12_SAFEBAG) *bags; 149 int i, bagnid; 150 PKCS7 *p7; 151 ASN1_OCTET_STRING *keyid = NULL; 152 153 char keymatch = 0; 154 if (!(asafes = PKCS12_unpack_authsafes (p12))) return 0; 155 for (i = 0; i < sk_PKCS7_num (asafes); i++) { 156 p7 = sk_PKCS7_value (asafes, i); 157 bagnid = OBJ_obj2nid (p7->type); 158 if (bagnid == NID_pkcs7_data) { 159 bags = PKCS12_unpack_p7data(p7); 160 } else if (bagnid == NID_pkcs7_encrypted) { 161 bags = PKCS12_unpack_p7encdata(p7, pass, passlen); 162 } else continue; 163 if (!bags) { 164 sk_PKCS7_pop_free(asafes, PKCS7_free); 165 return 0; 166 } 167 if (!parse_bags(bags, pass, passlen, pkey, cert, ca, 168 &keyid, &keymatch)) { 169 sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); 170 sk_PKCS7_pop_free(asafes, PKCS7_free); 171 return 0; 172 } 173 sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); 174 } 175 sk_PKCS7_pop_free(asafes, PKCS7_free); 176 if (keyid) M_ASN1_OCTET_STRING_free(keyid); 177 return 1; 178 } 179 180 181 static int parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass, 182 int passlen, EVP_PKEY **pkey, X509 **cert, 183 STACK_OF(X509) **ca, ASN1_OCTET_STRING **keyid, 184 char *keymatch) 185 { 186 int i; 187 for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) { 188 if (!parse_bag(sk_PKCS12_SAFEBAG_value (bags, i), 189 pass, passlen, pkey, cert, ca, keyid, 190 keymatch)) return 0; 191 } 192 return 1; 193 } 194 195 #define MATCH_KEY 0x1 196 #define MATCH_CERT 0x2 197 #define MATCH_ALL 0x3 198 199 static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, 200 EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca, 201 ASN1_OCTET_STRING **keyid, 202 char *keymatch) 203 { 204 PKCS8_PRIV_KEY_INFO *p8; 205 X509 *x509; 206 ASN1_OCTET_STRING *lkey = NULL, *ckid = NULL; 207 ASN1_TYPE *attrib; 208 ASN1_BMPSTRING *fname = NULL; 209 210 if ((attrib = PKCS12_get_attr (bag, NID_friendlyName))) 211 fname = attrib->value.bmpstring; 212 213 if ((attrib = PKCS12_get_attr (bag, NID_localKeyID))) { 214 lkey = attrib->value.octet_string; 215 ckid = lkey; 216 } 217 218 /* Check for any local key id matching (if needed) */ 219 if (lkey && ((*keymatch & MATCH_ALL) != MATCH_ALL)) { 220 if (*keyid) { 221 if (M_ASN1_OCTET_STRING_cmp(*keyid, lkey)) lkey = NULL; 222 } else { 223 if (!(*keyid = M_ASN1_OCTET_STRING_dup(lkey))) { 224 PKCS12err(PKCS12_F_PARSE_BAG,ERR_R_MALLOC_FAILURE); 225 return 0; 226 } 227 } 228 } 229 230 switch (M_PKCS12_bag_type(bag)) 231 { 232 case NID_keyBag: 233 if (!lkey || !pkey) return 1; 234 if (!(*pkey = EVP_PKCS82PKEY(bag->value.keybag))) return 0; 235 *keymatch |= MATCH_KEY; 236 break; 237 238 case NID_pkcs8ShroudedKeyBag: 239 if (!lkey || !pkey) return 1; 240 if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen))) 241 return 0; 242 *pkey = EVP_PKCS82PKEY(p8); 243 PKCS8_PRIV_KEY_INFO_free(p8); 244 if (!(*pkey)) return 0; 245 *keymatch |= MATCH_KEY; 246 break; 247 248 case NID_certBag: 249 if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate ) 250 return 1; 251 if (!(x509 = PKCS12_certbag2x509(bag))) return 0; 252 if(ckid) 253 { 254 if (!X509_keyid_set1(x509, ckid->data, ckid->length)) 255 { 256 X509_free(x509); 257 return 0; 258 } 259 } 260 if(fname) { 261 int len, r; 262 unsigned char *data; 263 len = ASN1_STRING_to_UTF8(&data, fname); 264 if(len > 0) { 265 r = X509_alias_set1(x509, data, len); 266 OPENSSL_free(data); 267 if (!r) 268 { 269 X509_free(x509); 270 return 0; 271 } 272 } 273 } 274 275 276 if (lkey) { 277 *keymatch |= MATCH_CERT; 278 if (cert) *cert = x509; 279 else X509_free(x509); 280 } else { 281 if(ca) sk_X509_push (*ca, x509); 282 else X509_free(x509); 283 } 284 break; 285 286 case NID_safeContentsBag: 287 return parse_bags(bag->value.safes, pass, passlen, 288 pkey, cert, ca, keyid, keymatch); 289 break; 290 291 default: 292 return 1; 293 break; 294 } 295 return 1; 296 } 297 298