X-Git-Url: https://git.openssl.org/gitweb/?a=blobdiff_plain;f=apps%2Fpkcs12.c;h=9a7132088b299f2d35f93b1ab9493422229bb55d;hb=f03620ea15c4553de375258bc40bbf7a4092da90;hp=e445c24b9bd667cc9c140f74374e312612912648;hpb=1c3e4a366022c043ae87ff9715905e97582bf649;p=openssl.git diff --git a/apps/pkcs12.c b/apps/pkcs12.c index e445c24b9b..9a7132088b 100644 --- a/apps/pkcs12.c +++ b/apps/pkcs12.c @@ -1,11 +1,9 @@ /* pkcs12.c */ -#if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_SHA1) - /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL * project. */ /* ==================================================================== - * Copyright (c) 1999-2002 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -58,6 +56,9 @@ * */ +#include +#if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_SHA1) + #include #include #include @@ -83,10 +84,11 @@ int dump_certs_keys_p12(BIO *out, PKCS12 *p12, char *pass, int passlen, int opti int dump_certs_pkeys_bags(BIO *out, STACK_OF(PKCS12_SAFEBAG) *bags, char *pass, int passlen, int options, char *pempass); int dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bags, char *pass, int passlen, int options, char *pempass); -int print_attribs(BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst, char *name); +int print_attribs(BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst,const char *name); void hex_prin(BIO *out, unsigned char *buf, int len); int alg_print(BIO *x, X509_ALGOR *alg); int cert_load(BIO *in, STACK_OF(X509) *sk); +static int set_pbe(BIO *err, int *ppbe, const char *str); int MAIN(int, char **); @@ -119,8 +121,11 @@ int MAIN(int argc, char **argv) char *passargin = NULL, *passargout = NULL, *passarg = NULL; char *passin = NULL, *passout = NULL; char *inrand = NULL; + char *macalg = NULL; char *CApath = NULL, *CAfile = NULL; +#ifndef OPENSSL_NO_ENGINE char *engine=NULL; +#endif apps_startup(); @@ -150,14 +155,22 @@ int MAIN(int argc, char **argv) cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; else if (!strcmp (*args, "-export")) export_cert = 1; else if (!strcmp (*args, "-des")) enc=EVP_des_cbc(); + else if (!strcmp (*args, "-des3")) enc = EVP_des_ede3_cbc(); #ifndef OPENSSL_NO_IDEA else if (!strcmp (*args, "-idea")) enc=EVP_idea_cbc(); #endif - else if (!strcmp (*args, "-des3")) enc = EVP_des_ede3_cbc(); +#ifndef OPENSSL_NO_SEED + else if (!strcmp(*args, "-seed")) enc=EVP_seed_cbc(); +#endif #ifndef OPENSSL_NO_AES else if (!strcmp(*args,"-aes128")) enc=EVP_aes_128_cbc(); else if (!strcmp(*args,"-aes192")) enc=EVP_aes_192_cbc(); else if (!strcmp(*args,"-aes256")) enc=EVP_aes_256_cbc(); +#endif +#ifndef OPENSSL_NO_CAMELLIA + else if (!strcmp(*args,"-camellia128")) enc=EVP_camellia_128_cbc(); + else if (!strcmp(*args,"-camellia192")) enc=EVP_camellia_192_cbc(); + else if (!strcmp(*args,"-camellia256")) enc=EVP_camellia_256_cbc(); #endif else if (!strcmp (*args, "-noiter")) iter = 1; else if (!strcmp (*args, "-maciter")) @@ -166,32 +179,18 @@ int MAIN(int argc, char **argv) maciter = 1; else if (!strcmp (*args, "-nomac")) maciter = -1; + else if (!strcmp (*args, "-macalg")) + if (args[1]) { + args++; + macalg = *args; + } else badarg = 1; else if (!strcmp (*args, "-nodes")) enc=NULL; else if (!strcmp (*args, "-certpbe")) { - if (args[1]) { - args++; - if (!strcmp(*args, "NONE")) - cert_pbe = -1; - cert_pbe=OBJ_txt2nid(*args); - if(cert_pbe == NID_undef) { - BIO_printf(bio_err, - "Unknown PBE algorithm %s\n", *args); - badarg = 1; - } - } else badarg = 1; + if (!set_pbe(bio_err, &cert_pbe, *++args)) + badarg = 1; } else if (!strcmp (*args, "-keypbe")) { - if (args[1]) { - args++; - if (!strcmp(*args, "NONE")) - key_pbe = -1; - else - key_pbe=OBJ_txt2nid(*args); - if(key_pbe == NID_undef) { - BIO_printf(bio_err, - "Unknown PBE algorithm %s\n", *args); - badarg = 1; - } - } else badarg = 1; + if (!set_pbe(bio_err, &key_pbe, *++args)) + badarg = 1; } else if (!strcmp (*args, "-rand")) { if (args[1]) { args++; @@ -259,11 +258,13 @@ int MAIN(int argc, char **argv) args++; CAfile = *args; } else badarg = 1; +#ifndef OPENSSL_NO_ENGINE } else if (!strcmp(*args,"-engine")) { if (args[1]) { args++; engine = *args; } else badarg = 1; +#endif } else badarg = 1; } else badarg = 1; @@ -295,30 +296,45 @@ int MAIN(int argc, char **argv) #ifndef OPENSSL_NO_IDEA BIO_printf (bio_err, "-idea encrypt private keys with idea\n"); #endif +#ifndef OPENSSL_NO_SEED + BIO_printf (bio_err, "-seed encrypt private keys with seed\n"); +#endif #ifndef OPENSSL_NO_AES BIO_printf (bio_err, "-aes128, -aes192, -aes256\n"); BIO_printf (bio_err, " encrypt PEM output with cbc aes\n"); +#endif +#ifndef OPENSSL_NO_CAMELLIA + BIO_printf (bio_err, "-camellia128, -camellia192, -camellia256\n"); + BIO_printf (bio_err, " encrypt PEM output with cbc camellia\n"); #endif BIO_printf (bio_err, "-nodes don't encrypt private keys\n"); BIO_printf (bio_err, "-noiter don't use encryption iteration\n"); + BIO_printf (bio_err, "-nomaciter don't use MAC iteration\n"); BIO_printf (bio_err, "-maciter use MAC iteration\n"); + BIO_printf (bio_err, "-nomac don't generate MAC\n"); BIO_printf (bio_err, "-twopass separate MAC, encryption passwords\n"); BIO_printf (bio_err, "-descert encrypt PKCS#12 certificates with triple DES (default RC2-40)\n"); BIO_printf (bio_err, "-certpbe alg specify certificate PBE algorithm (default RC2-40)\n"); BIO_printf (bio_err, "-keypbe alg specify private key PBE algorithm (default 3DES)\n"); + BIO_printf (bio_err, "-macalg alg digest algorithm used in MAC (default SHA1)\n"); BIO_printf (bio_err, "-keyex set MS key exchange type\n"); BIO_printf (bio_err, "-keysig set MS key signature type\n"); BIO_printf (bio_err, "-password p set import/export password source\n"); BIO_printf (bio_err, "-passin p input file pass phrase source\n"); BIO_printf (bio_err, "-passout p output file pass phrase source\n"); +#ifndef OPENSSL_NO_ENGINE BIO_printf (bio_err, "-engine e use engine e, possibly a hardware device.\n"); +#endif BIO_printf(bio_err, "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR); BIO_printf(bio_err, " load the file (or the files in the directory) into\n"); BIO_printf(bio_err, " the random number generator\n"); + BIO_printf(bio_err, "-CSP name Microsoft CSP name\n"); goto end; } +#ifndef OPENSSL_NO_ENGINE e = setup_engine(bio_err, engine, 0); +#endif if(passarg) { if(export_cert) passargout = passarg; @@ -402,6 +418,7 @@ int MAIN(int argc, char **argv) EVP_PKEY *key = NULL; X509 *ucert = NULL, *x = NULL; STACK_OF(X509) *certs=NULL; + const EVP_MD *macmd = NULL; unsigned char *catmp = NULL; int i; @@ -517,8 +534,11 @@ int MAIN(int argc, char **argv) X509_free(sk_X509_value(chain2, 0)); sk_X509_free(chain2); } else { - BIO_printf (bio_err, "Error %s getting chain.\n", + if (vret >= 0) + BIO_printf (bio_err, "Error %s getting chain.\n", X509_verify_cert_error_string(vret)); + else + ERR_print_errors(bio_err); goto export_end; } } @@ -530,6 +550,10 @@ int MAIN(int argc, char **argv) catmp = (unsigned char *)sk_value(canames, i); X509_alias_set1(sk_X509_value(certs, i), catmp, -1); } + + if (csp_name && key) + EVP_PKEY_add1_attr_by_NID(key, NID_ms_csp_name, + MBSTRING_ASC, (unsigned char *)csp_name, -1); #ifdef CRYPTO_MDEBUG @@ -543,14 +567,14 @@ int MAIN(int argc, char **argv) BIO_printf (bio_err, "Can't read Password\n"); goto export_end; } - if (!twopass) strcpy(macpass, pass); + if (!twopass) BUF_strlcpy(macpass, pass, sizeof macpass); #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); CRYPTO_push_info("creating PKCS#12 structure"); #endif - p12 = PKCS12_create(pass, name, key, ucert, certs, + p12 = PKCS12_create(cpass, name, key, ucert, certs, key_pbe, cert_pbe, iter, -1, keytype); if (!p12) @@ -559,8 +583,18 @@ int MAIN(int argc, char **argv) goto export_end; } + if (macalg) + { + macmd = EVP_get_digestbyname(macalg); + if (!macmd) + { + BIO_printf(bio_err, "Unknown digest algorithm %s\n", + macalg); + } + } + if (maciter != -1) - PKCS12_set_mac(p12, mpass, -1, NULL, 0, maciter, NULL); + PKCS12_set_mac(p12, mpass, -1, NULL, 0, maciter, macmd); #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); @@ -605,7 +639,7 @@ int MAIN(int argc, char **argv) CRYPTO_pop_info(); #endif - if (!twopass) strcpy(macpass, pass); + if (!twopass) BUF_strlcpy(macpass, pass, sizeof macpass); if (options & INFO) BIO_printf (bio_err, "MAC Iteration %ld\n", p12->mac->iter ? ASN1_INTEGER_get (p12->mac->iter) : 1); if(macver) { @@ -613,7 +647,7 @@ int MAIN(int argc, char **argv) CRYPTO_push_info("verify MAC"); #endif /* If we enter empty password try no password first */ - if(!macpass[0] && PKCS12_verify_mac(p12, NULL, 0)) { + if(!mpass[0] && PKCS12_verify_mac(p12, NULL, 0)) { /* If mac and crypto pass the same set it to NULL too */ if(!twopass) cpass = NULL; } else if (!PKCS12_verify_mac(p12, mpass, -1)) { @@ -657,9 +691,10 @@ int MAIN(int argc, char **argv) int dump_certs_keys_p12 (BIO *out, PKCS12 *p12, char *pass, int passlen, int options, char *pempass) { - STACK_OF(PKCS7) *asafes; + STACK_OF(PKCS7) *asafes = NULL; STACK_OF(PKCS12_SAFEBAG) *bags; int i, bagnid; + int ret = 0; PKCS7 *p7; if (!( asafes = PKCS12_unpack_authsafes(p12))) return 0; @@ -677,16 +712,22 @@ int dump_certs_keys_p12 (BIO *out, PKCS12 *p12, char *pass, } bags = PKCS12_unpack_p7encdata(p7, pass, passlen); } else continue; - if (!bags) return 0; + if (!bags) goto err; if (!dump_certs_pkeys_bags (out, bags, pass, passlen, options, pempass)) { sk_PKCS12_SAFEBAG_pop_free (bags, PKCS12_SAFEBAG_free); - return 0; + goto err; } sk_PKCS12_SAFEBAG_pop_free (bags, PKCS12_SAFEBAG_free); + bags = NULL; } - sk_PKCS7_pop_free (asafes, PKCS7_free); - return 1; + ret = 1; + + err: + + if (asafes) + sk_PKCS7_pop_free (asafes, PKCS7_free); + return ret; } int dump_certs_pkeys_bags (BIO *out, STACK_OF(PKCS12_SAFEBAG) *bags, @@ -781,7 +822,7 @@ int get_cert_chain (X509 *cert, X509_STORE *store, STACK_OF(X509) **chain) { X509_STORE_CTX store_ctx; STACK_OF(X509) *chn; - int i; + int i = 0; /* FIXME: Should really check the return status of X509_STORE_CTX_init * for an error, but how that fits into the return value of this @@ -789,13 +830,17 @@ int get_cert_chain (X509 *cert, X509_STORE *store, STACK_OF(X509) **chain) X509_STORE_CTX_init(&store_ctx, store, cert, NULL); if (X509_verify_cert(&store_ctx) <= 0) { i = X509_STORE_CTX_get_error (&store_ctx); + if (i == 0) + /* avoid returning 0 if X509_verify_cert() did not + * set an appropriate error value in the context */ + i = -1; + chn = NULL; goto err; - } - chn = X509_STORE_CTX_get1_chain(&store_ctx); - i = 0; - *chain = chn; + } else + chn = X509_STORE_CTX_get1_chain(&store_ctx); err: X509_STORE_CTX_cleanup(&store_ctx); + *chain = chn; return i; } @@ -803,13 +848,16 @@ err: int alg_print (BIO *x, X509_ALGOR *alg) { PBEPARAM *pbe; - unsigned char *p; + const unsigned char *p; p = alg->parameter->value.sequence->data; - pbe = d2i_PBEPARAM (NULL, &p, alg->parameter->value.sequence->length); - BIO_printf (bio_err, "%s, Iteration %d\n", - OBJ_nid2ln(OBJ_obj2nid(alg->algorithm)), ASN1_INTEGER_get(pbe->iter)); + pbe = d2i_PBEPARAM(NULL, &p, alg->parameter->value.sequence->length); + if (!pbe) + return 1; + BIO_printf (bio_err, "%s, Iteration %ld\n", + OBJ_nid2ln(OBJ_obj2nid(alg->algorithm)), + ASN1_INTEGER_get(pbe->iter)); PBEPARAM_free (pbe); - return 0; + return 1; } /* Load all certificates from a given file */ @@ -841,7 +889,7 @@ int cert_load(BIO *in, STACK_OF(X509) *sk) /* Generalised attribute print: handle PKCS#8 and bag attributes */ -int print_attribs (BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst, char *name) +int print_attribs (BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst,const char *name) { X509_ATTRIBUTE *attr; ASN1_TYPE *av; @@ -902,4 +950,22 @@ void hex_prin(BIO *out, unsigned char *buf, int len) for (i = 0; i < len; i++) BIO_printf (out, "%02X ", buf[i]); } +static int set_pbe(BIO *err, int *ppbe, const char *str) + { + if (!str) + return 0; + if (!strcmp(str, "NONE")) + { + *ppbe = -1; + return 1; + } + *ppbe=OBJ_txt2nid(str); + if (*ppbe == NID_undef) + { + BIO_printf(bio_err, "Unknown PBE algorithm %s\n", str); + return 0; + } + return 1; + } + #endif