#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <pem.h>
-#include <err.h>
-#include "pkcs12.h"
+#include <openssl/des.h>
+#include <openssl/pem.h>
+#include <openssl/err.h>
+#include <openssl/pkcs12.h>
#include "apps.h"
#define PROG pkcs12_main
EVP_CIPHER *enc;
-#define _ITER_ 1000
#define NOKEYS 0x1
#define NOCERTS 0x2
#define CLCERTS 0x8
#define CACERTS 0x10
-#ifndef NOPROTO
-int get_cert_chain(X509 *cert, STACK **chain);
+int get_cert_chain(X509 *cert, STACK_OF(X509) **chain);
+int dump_cert_text (BIO *out, X509 *x);
int dump_certs_keys_p12(BIO *out, PKCS12 *p12, char *pass, int passlen, int options);
int dump_certs_pkeys_bags(BIO *out, STACK *bags, char *pass, int passlen, int options);
int dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bags, char *pass, int passlen, int options);
-int print_attribs(BIO *out, STACK *attrlst, char *name);
+int print_attribs(BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst, 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 *sk);
-#else
-int get_cert_chain();
-int dump_certs_keys_p12();
-int dump_certs_pkeys_bags();
-int dump_certs_pkeys_bag();
-int print_attribs();
-void hex_prin();
-int alg_print();
-int cert_load();
-#endif
-
+int cert_load(BIO *in, STACK_OF(X509) *sk);
int MAIN(int argc, char **argv)
{
char *infile=NULL, *outfile=NULL, *keyname = NULL;
int options = 0;
int chain = 0;
int badarg = 0;
- int iter = _ITER_;
+ int iter = PKCS12_DEFAULT_ITER;
int maciter = 1;
int twopass = 0;
int keytype = 0;
int cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC;
int ret = 1;
int macver = 1;
+ int noprompt = 0;
STACK *canames = NULL;
+ char *cpass = NULL, *mpass = NULL;
apps_startup();
#endif
else if (!strcmp (*args, "-des3")) enc = EVP_des_ede3_cbc();
else if (!strcmp (*args, "-noiter")) iter = 1;
- else if (!strcmp (*args, "-maciter")) maciter = _ITER_;
+ else if (!strcmp (*args, "-maciter"))
+ maciter = PKCS12_DEFAULT_ITER;
else if (!strcmp (*args, "-nodes")) enc=NULL;
else if (!strcmp (*args, "-inkey")) {
if (args[1]) {
args++;
outfile = *args;
} else badarg = 1;
+ } else if (!strcmp (*args, "-envpass")) {
+ if (args[1]) {
+ args++;
+ if(!(cpass = getenv(*args))) {
+ BIO_printf(bio_err,
+ "Can't read environment variable %s\n", *args);
+ goto end;
+ }
+ noprompt = 1;
+ } else badarg = 1;
+ } else if (!strcmp (*args, "-password")) {
+ if (args[1]) {
+ args++;
+ cpass = *args;
+ noprompt = 1;
+ } else badarg = 1;
} else badarg = 1;
} else badarg = 1;
BIO_printf (bio_err, "-descert encrypt PKCS#12 certificates with triple DES (default RC2-40)\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 (NOT RECOMMENDED)\n");
+ BIO_printf (bio_err, "-envpass p set import/export password from environment\n");
goto end;
}
+ if(cpass) mpass = cpass;
+ else {
+ cpass = pass;
+ mpass = macpass;
+ }
+
ERR_load_crypto_strings();
in = BIO_new (BIO_s_file());
PKCS8_PRIV_KEY_INFO *p8;
PKCS7 *authsafe;
X509 *cert, *ucert = NULL;
- STACK *certs;
+ STACK_OF(X509) *certs;
char *catmp;
int i, pmatch = 0;
unsigned char keyid[EVP_MAX_MD_SIZE];
goto end;
}
- certs = sk_new(NULL);
+ certs = sk_X509_new(NULL);
/* Load in all certs in input file */
if(!cert_load(in, certs)) {
/* Find certificate (if any) matching private key */
- for(i = 0; i < sk_num(certs); i++) {
- cert = (X509 *)sk_value(certs, i);
+ for(i = 0; i < sk_X509_num(certs); i++) {
+ cert = sk_X509_value(certs, i);
if(X509_check_private_key(cert, key)) {
ucert = cert;
break;
/* If chaining get chain from user cert */
if (chain) {
int vret;
- STACK *chain2;
+ STACK_OF(X509) *chain2;
vret = get_cert_chain (ucert, &chain2);
if (vret) {
goto end;
}
/* Exclude verified certificate */
- for (i = 1; i < sk_num (chain2) ; i++)
- sk_push(certs, sk_value (chain2, i));
- sk_free(chain2);
+ for (i = 1; i < sk_X509_num (chain2) ; i++)
+ sk_X509_push(certs, sk_X509_value (chain2, i));
+ sk_X509_free(chain2);
}
/* We now have loads of certificates: include them all */
- for(i = 0; i < sk_num(certs); i++) {
- cert = (X509 *)sk_value(certs, i);
+ for(i = 0; i < sk_X509_num(certs); i++) {
+ cert = sk_X509_value(certs, i);
bag = M_PKCS12_x5092certbag(cert);
/* If it matches private key mark it */
if(cert == ucert) {
if (canames) sk_free(canames);
- if(EVP_read_pw_string (pass, 50, "Enter Export Password:", 1)) {
+ if(!noprompt &&
+ EVP_read_pw_string(pass, 50, "Enter Export Password:", 1)) {
BIO_printf (bio_err, "Can't read Password\n");
goto end;
}
if (!twopass) strcpy(macpass, pass);
/* Turn certbags into encrypted authsafe */
- authsafe = PKCS12_pack_p7encdata (cert_pbe, pass, -1, NULL, 0,
+ authsafe = PKCS12_pack_p7encdata (cert_pbe, cpass, -1, NULL, 0,
iter, bags);
sk_pop_free(bags, PKCS12_SAFEBAG_free);
EVP_PKEY_free(key);
if(keytype) PKCS8_add_keyusage(p8, keytype);
bag = PKCS12_MAKE_SHKEYBAG (NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
- pass, -1, NULL, 0, iter, p8);
+ cpass, -1, NULL, 0, iter, p8);
PKCS8_PRIV_KEY_INFO_free(p8);
if (name) PKCS12_add_friendlyname (bag, name, -1);
- PKCS12_add_localkeyid (bag, keyid, keyidlen);
+ if(pmatch) PKCS12_add_localkeyid (bag, keyid, keyidlen);
bags = sk_new(NULL);
sk_push (bags, (char *)bag);
/* Turn it into unencrypted safe bag */
sk_pop_free(safes, PKCS7_free);
- PKCS12_set_mac (p12, macpass, -1, NULL, 0, maciter, NULL);
+ PKCS12_set_mac (p12, mpass, -1, NULL, 0, maciter, NULL);
i2d_PKCS12_bio (out, p12);
ret = 0;
goto end;
-}
+ }
if (!(p12 = d2i_PKCS12_bio (in, NULL))) {
ERR_print_errors(bio_err);
goto end;
}
- if(EVP_read_pw_string (pass, 50, "Enter Import Password:", 0)) {
+ if(!noprompt && EVP_read_pw_string(pass, 50, "Enter Import Password:", 0)) {
BIO_printf (bio_err, "Can't read Password\n");
goto end;
}
if (options & INFO) BIO_printf (bio_err, "MAC Iteration %ld\n", p12->mac->iter ? ASN1_INTEGER_get (p12->mac->iter) : 1);
if(macver) {
- if (!PKCS12_verify_mac (p12, macpass, -1)) {
+ if (!PKCS12_verify_mac (p12, mpass, -1)) {
BIO_printf (bio_err, "Mac verify errror: invalid password?\n");
ERR_print_errors (bio_err);
goto end;
} else BIO_printf (bio_err, "MAC verified OK\n");
}
- if (!dump_certs_keys_p12 (out, p12, pass, -1, options)) {
+ if (!dump_certs_keys_p12 (out, p12, cpass, -1, options)) {
BIO_printf(bio_err, "Error outputting keys and certificates\n");
ERR_print_errors (bio_err);
goto end;
PKCS12_free(p12);
ret = 0;
end:
+ BIO_free(out);
EXIT(ret);
}
/* Hope this is OK .... */
-int get_cert_chain (X509 *cert, STACK **chain)
+int get_cert_chain (X509 *cert, STACK_OF(X509) **chain)
{
X509_STORE *store;
X509_STORE_CTX store_ctx;
- STACK *chn;
+ STACK_OF(X509) *chn;
int i;
X509 *x;
store = X509_STORE_new ();
i = X509_STORE_CTX_get_error (&store_ctx);
goto err;
}
- chn = sk_dup(X509_STORE_CTX_get_chain (&store_ctx));
- for (i = 0; i < sk_num(chn); i++) {
- x = (X509 *)sk_value(chn, i);
+ chn = sk_X509_dup(X509_STORE_CTX_get_chain (&store_ctx));
+ for (i = 0; i < sk_X509_num(chn); i++) {
+ x = sk_X509_value(chn, i);
CRYPTO_add(&x->references,1,CRYPTO_LOCK_X509);
}
i = 0;
/* Load all certificates from a given file */
-int cert_load(BIO *in, STACK *sk)
+int cert_load(BIO *in, STACK_OF(X509) *sk)
{
int ret;
X509 *cert;
ret = 0;
while((cert = PEM_read_bio_X509(in, NULL, NULL))) {
ret = 1;
- sk_push(sk, (char *)cert);
+ sk_X509_push(sk, cert);
}
if(ret) ERR_clear_error();
return ret;
/* Generalised attribute print: handle PKCS#8 and bag attributes */
-int print_attribs (BIO *out, STACK *attrlst, char *name)
+int print_attribs (BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst, char *name)
{
X509_ATTRIBUTE *attr;
ASN1_TYPE *av;
BIO_printf(out, "%s: <No Attributes>\n", name);
return 1;
}
- if(!sk_num(attrlst)) {
+ if(!sk_X509_ATTRIBUTE_num(attrlst)) {
BIO_printf(out, "%s: <Empty Attributes>\n", name);
return 1;
}
BIO_printf(out, "%s\n", name);
- for(i = 0; i < sk_num(attrlst); i++) {
- attr = (X509_ATTRIBUTE *) sk_value(attrlst, i);
+ for(i = 0; i < sk_X509_ATTRIBUTE_num(attrlst); i++) {
+ attr = sk_X509_ATTRIBUTE_value(attrlst, i);
attr_nid = OBJ_obj2nid(attr->object);
BIO_printf(out, " ");
if(attr_nid == NID_undef) {
BIO_printf(out, ": ");
} else BIO_printf(out, "%s: ", OBJ_nid2ln(attr_nid));
- if(sk_num(attr->value.set)) {
- av = (ASN1_TYPE *)sk_value(attr->value.set, 0);
+ if(sk_ASN1_TYPE_num(attr->value.set)) {
+ av = sk_ASN1_TYPE_value(attr->value.set, 0);
switch(av->type) {
case V_ASN1_BMPSTRING:
value = uni2asc(av->value.bmpstring->data,