Beispiel #1
9
int keygen_init(void)
{
	m_bignumber = BN_new();
	if(!m_bignumber)
	{
		fprintf(stderr, "Failed to init bignumber\n");
		return -1;
	}
	m_rsa=RSA_new();
	if(!m_rsa)
	{
		fprintf(stderr, "Failed to create RSA context\n");
		return -1;
	}
	if(!BN_set_word(m_bignumber, RSA_F4) || !RSA_generate_key_ex(m_rsa,RSA_KEY_BITS,m_bignumber,NULL))
	{
		fprintf(stderr, "Failed to generate RSA key\n");
		return -1;
	}
	m_evpkey=EVP_PKEY_new();
	if(!EVP_PKEY_set1_RSA(m_evpkey, m_rsa))
	{
		fprintf(stderr, "Unable to convert RSA key to EVP key\n");
		return -1;
	}
	m_p8info=EVP_PKEY2PKCS8(m_evpkey);
	if(!m_p8info)
	{
		fprintf(stderr, "Failed to convert EVP to PKCS8\n");
		return -1;
	}
	return 0;
}
// Encode into PKCS#8 DER
ByteString OSSLECPrivateKey::PKCS8Encode()
{
	ByteString der;
	if (eckey == NULL) return der;
	EVP_PKEY* pkey = EVP_PKEY_new();
	if (pkey == NULL) return der;
	if (!EVP_PKEY_set1_EC_KEY(pkey, eckey))
	{
		EVP_PKEY_free(pkey);
		return der;
	}
	PKCS8_PRIV_KEY_INFO* p8inf = EVP_PKEY2PKCS8(pkey);
	EVP_PKEY_free(pkey);
	if (p8inf == NULL) return der;
	int len = i2d_PKCS8_PRIV_KEY_INFO(p8inf, NULL);
	if (len < 0)
	{
		PKCS8_PRIV_KEY_INFO_free(p8inf);
		return der;
	}
	der.resize(len);
	unsigned char* priv = &der[0];
	int len2 = i2d_PKCS8_PRIV_KEY_INFO(p8inf, &priv);
	PKCS8_PRIV_KEY_INFO_free(p8inf);
	if (len2 != len) der.wipe();
	return der;
}
Beispiel #3
0
int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key)
	{
	PKCS8_PRIV_KEY_INFO *p8inf;
	int ret;
	p8inf = EVP_PKEY2PKCS8(key);
	if(!p8inf) return 0;
	ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf);
	PKCS8_PRIV_KEY_INFO_free(p8inf);
	return ret;
	}
int i2d_PKCS8PrivateKeyInfo_fp(TINYCLR_SSL_FILE *fp, EVP_PKEY *key)
	{
	PKCS8_PRIV_KEY_INFO *p8inf;
	int ret;
	p8inf = EVP_PKEY2PKCS8(key);
	if(!p8inf) return 0;
	ret = i2d_PKCS8_PRIV_KEY_INFO_fp(fp, p8inf);
	PKCS8_PRIV_KEY_INFO_free(p8inf);
	return ret;
	}
Beispiel #5
0
int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp)
{
    if (a->ameth && a->ameth->old_priv_encode)
    {
        return a->ameth->old_priv_encode(a, pp);
    }
    if (a->ameth && a->ameth->priv_encode) {
        PKCS8_PRIV_KEY_INFO *p8 = EVP_PKEY2PKCS8(a);
        int ret = i2d_PKCS8_PRIV_KEY_INFO(p8,pp);
        PKCS8_PRIV_KEY_INFO_free(p8);
        return ret;
    }
    ASN1err(ASN1_F_I2D_PRIVATEKEY,ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
    return(-1);
}
Beispiel #6
0
static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, int nid,
                      const EVP_CIPHER *enc, char *kstr, int klen,
                      pem_password_cb *cb, void *u)
{
    X509_SIG *p8;
    PKCS8_PRIV_KEY_INFO *p8inf;
    char buf[PEM_BUFSIZE];
    int ret;

    if ((p8inf = EVP_PKEY2PKCS8(x)) == NULL) {
        PEMerr(PEM_F_DO_PK8PKEY, PEM_R_ERROR_CONVERTING_PRIVATE_KEY);
        return 0;
    }
    if (enc || (nid != -1)) {
        if (!kstr) {
            if (!cb)
                klen = PEM_def_callback(buf, PEM_BUFSIZE, 1, u);
            else
                klen = cb(buf, PEM_BUFSIZE, 1, u);
            if (klen <= 0) {
                PEMerr(PEM_F_DO_PK8PKEY, PEM_R_READ_KEY);
                PKCS8_PRIV_KEY_INFO_free(p8inf);
                return 0;
            }

            kstr = buf;
        }
        p8 = PKCS8_encrypt(nid, enc, kstr, klen, NULL, 0, 0, p8inf);
        if (kstr == buf)
            OPENSSL_cleanse(buf, klen);
        PKCS8_PRIV_KEY_INFO_free(p8inf);
        if (p8 == NULL)
            return 0;
        if (isder)
            ret = i2d_PKCS8_bio(bp, p8);
        else
            ret = PEM_write_bio_PKCS8(bp, p8);
        X509_SIG_free(p8);
        return ret;
    } else {
        if (isder)
            ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf);
        else
            ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(bp, p8inf);
        PKCS8_PRIV_KEY_INFO_free(p8inf);
        return ret;
    }
}
Beispiel #7
0
int MAIN(int argc, char **argv)
{
    ENGINE *e = NULL;
    char *infile=NULL, *outfile=NULL, *keyname = NULL;	
    char *certfile=NULL;
    BIO *in=NULL, *out = NULL;
    char **args;
    char *name = NULL;
    char *csp_name = NULL;
    PKCS12 *p12 = NULL;
    char pass[50], macpass[50];
    int export_cert = 0;
    int options = 0;
    int chain = 0;
    int badarg = 0;
    int iter = PKCS12_DEFAULT_ITER;
    int maciter = PKCS12_DEFAULT_ITER;
    int twopass = 0;
    int keytype = 0;
    int cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC;
    int key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
    int ret = 1;
    int macver = 1;
    int noprompt = 0;
    STACK *canames = NULL;
    char *cpass = NULL, *mpass = NULL;
    char *passargin = NULL, *passargout = NULL, *passarg = NULL;
    char *passin = NULL, *passout = NULL;
    char *inrand = NULL;
    char *CApath = NULL, *CAfile = NULL;
    char *engine=NULL;

    apps_startup();

    enc = EVP_des_ede3_cbc();
    if (bio_err == NULL ) bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);

	if (!load_config(bio_err, NULL))
		goto end;

    args = argv + 1;


    while (*args) {
	if (*args[0] == '-') {
		if (!strcmp (*args, "-nokeys")) options |= NOKEYS;
		else if (!strcmp (*args, "-keyex")) keytype = KEY_EX;
		else if (!strcmp (*args, "-keysig")) keytype = KEY_SIG;
		else if (!strcmp (*args, "-nocerts")) options |= NOCERTS;
		else if (!strcmp (*args, "-clcerts")) options |= CLCERTS;
		else if (!strcmp (*args, "-cacerts")) options |= CACERTS;
		else if (!strcmp (*args, "-noout")) options |= (NOKEYS|NOCERTS);
		else if (!strcmp (*args, "-info")) options |= INFO;
		else if (!strcmp (*args, "-chain")) chain = 1;
		else if (!strcmp (*args, "-twopass")) twopass = 1;
		else if (!strcmp (*args, "-nomacver")) macver = 0;
		else if (!strcmp (*args, "-descert"))
    			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();
#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_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
		else if (!strcmp (*args, "-noiter")) iter = 1;
		else if (!strcmp (*args, "-maciter"))
					 maciter = PKCS12_DEFAULT_ITER;
		else if (!strcmp (*args, "-nomaciter"))
					 maciter = 1;
		else if (!strcmp (*args, "-nodes")) enc=NULL;
		else if (!strcmp (*args, "-certpbe")) {
			if (args[1]) {
				args++;
				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;
		} else if (!strcmp (*args, "-keypbe")) {
			if (args[1]) {
				args++;
				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;
		} else if (!strcmp (*args, "-rand")) {
		    if (args[1]) {
			args++;	
			inrand = *args;
		    } else badarg = 1;
		} else if (!strcmp (*args, "-inkey")) {
		    if (args[1]) {
			args++;	
			keyname = *args;
		    } else badarg = 1;
		} else if (!strcmp (*args, "-certfile")) {
		    if (args[1]) {
			args++;	
			certfile = *args;
		    } else badarg = 1;
		} else if (!strcmp (*args, "-name")) {
		    if (args[1]) {
			args++;	
			name = *args;
		    } else badarg = 1;
		} else if (!strcmp (*args, "-CSP")) {
		    if (args[1]) {
			args++;	
			csp_name = *args;
		    } else badarg = 1;
		} else if (!strcmp (*args, "-caname")) {
		    if (args[1]) {
			args++;	
			if (!canames) canames = sk_new_null();
			sk_push(canames, *args);
		    } else badarg = 1;
		} else if (!strcmp (*args, "-in")) {
		    if (args[1]) {
			args++;	
			infile = *args;
		    } else badarg = 1;
		} else if (!strcmp (*args, "-out")) {
		    if (args[1]) {
			args++;	
			outfile = *args;
		    } else badarg = 1;
		} else if (!strcmp(*args,"-passin")) {
		    if (args[1]) {
			args++;	
			passargin = *args;
		    } else badarg = 1;
		} else if (!strcmp(*args,"-passout")) {
		    if (args[1]) {
			args++;	
			passargout = *args;
		    } else badarg = 1;
		} else if (!strcmp (*args, "-password")) {
		    if (args[1]) {
			args++;	
			passarg = *args;
		    	noprompt = 1;
		    } else badarg = 1;
		} else if (!strcmp(*args,"-CApath")) {
		    if (args[1]) {
			args++;	
			CApath = *args;
		    } else badarg = 1;
		} else if (!strcmp(*args,"-CAfile")) {
		    if (args[1]) {
			args++;	
			CAfile = *args;
		    } else badarg = 1;
		} else if (!strcmp(*args,"-engine")) {
		    if (args[1]) {
			args++;	
			engine = *args;
		    } else badarg = 1;
		} else badarg = 1;

	} else badarg = 1;
	args++;
    }

    if (badarg) {
	BIO_printf (bio_err, "Usage: pkcs12 [options]\n");
	BIO_printf (bio_err, "where options are\n");
	BIO_printf (bio_err, "-export       output PKCS12 file\n");
	BIO_printf (bio_err, "-chain        add certificate chain\n");
	BIO_printf (bio_err, "-inkey file   private key if not infile\n");
	BIO_printf (bio_err, "-certfile f   add all certs in f\n");
	BIO_printf (bio_err, "-CApath arg   - PEM format directory of CA's\n");
	BIO_printf (bio_err, "-CAfile arg   - PEM format file of CA's\n");
	BIO_printf (bio_err, "-name \"name\"  use name as friendly name\n");
	BIO_printf (bio_err, "-caname \"nm\"  use nm as CA friendly name (can be used more than once).\n");
	BIO_printf (bio_err, "-in  infile   input filename\n");
	BIO_printf (bio_err, "-out outfile  output filename\n");
	BIO_printf (bio_err, "-noout        don't output anything, just verify.\n");
	BIO_printf (bio_err, "-nomacver     don't verify MAC.\n");
	BIO_printf (bio_err, "-nocerts      don't output certificates.\n");
	BIO_printf (bio_err, "-clcerts      only output client certificates.\n");
	BIO_printf (bio_err, "-cacerts      only output CA certificates.\n");
	BIO_printf (bio_err, "-nokeys       don't output private keys.\n");
	BIO_printf (bio_err, "-info         give info about PKCS#12 structure.\n");
	BIO_printf (bio_err, "-des          encrypt private keys with DES\n");
	BIO_printf (bio_err, "-des3         encrypt private keys with triple DES (default)\n");
#ifndef OPENSSL_NO_IDEA
	BIO_printf (bio_err, "-idea         encrypt private keys with idea\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
	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, "-maciter      use MAC iteration\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, "-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");
	BIO_printf (bio_err, "-engine e     use engine e, possibly a hardware device.\n");
	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");
    	goto end;
    }

    e = setup_engine(bio_err, engine, 0);

    if(passarg) {
	if(export_cert) passargout = passarg;
	else passargin = passarg;
    }

    if(!app_passwd(bio_err, passargin, passargout, &passin, &passout)) {
	BIO_printf(bio_err, "Error getting passwords\n");
	goto end;
    }

    if(!cpass) {
    	if(export_cert) cpass = passout;
    	else cpass = passin;
    }

    if(cpass) {
	mpass = cpass;
	noprompt = 1;
    } else {
	cpass = pass;
	mpass = macpass;
    }

    if(export_cert || inrand) {
    	app_RAND_load_file(NULL, bio_err, (inrand != NULL));
        if (inrand != NULL)
		BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
			app_RAND_load_files(inrand));
    }
    ERR_load_crypto_strings();

#ifdef CRYPTO_MDEBUG
    CRYPTO_push_info("read files");
#endif

    if (!infile) in = BIO_new_fp(stdin, BIO_NOCLOSE);
    else in = BIO_new_file(infile, "rb");
    if (!in) {
	    BIO_printf(bio_err, "Error opening input file %s\n",
						infile ? infile : "<stdin>");
	    perror (infile);
	    goto end;
   }

#if 0
   if (certfile) {
    	if(!(certsin = BIO_new_file(certfile, "r"))) {
	    BIO_printf(bio_err, "Can't open certificate file %s\n", certfile);
	    perror (certfile);
	    goto end;
	}
    }

    if (keyname) {
    	if(!(inkey = BIO_new_file(keyname, "r"))) {
	    BIO_printf(bio_err, "Can't key certificate file %s\n", keyname);
	    perror (keyname);
	    goto end;
	}
     }
#endif

#ifdef CRYPTO_MDEBUG
    CRYPTO_pop_info();
    CRYPTO_push_info("write files");
#endif

    if (!outfile) {
	out = BIO_new_fp(stdout, BIO_NOCLOSE);
#ifdef OPENSSL_SYS_VMS
	{
	    BIO *tmpbio = BIO_new(BIO_f_linebuffer());
	    out = BIO_push(tmpbio, out);
	}
#endif
    } else out = BIO_new_file(outfile, "wb");
    if (!out) {
	BIO_printf(bio_err, "Error opening output file %s\n",
						outfile ? outfile : "<stdout>");
	perror (outfile);
	goto end;
    }
    if (twopass) {
#ifdef CRYPTO_MDEBUG
    CRYPTO_push_info("read MAC password");
#endif
	if(EVP_read_pw_string (macpass, sizeof macpass, "Enter MAC Password:"******"Can't read Password\n");
    	    goto end;
       	}
#ifdef CRYPTO_MDEBUG
    CRYPTO_pop_info();
#endif
    }

    if (export_cert) {
	EVP_PKEY *key = NULL;
	STACK_OF(PKCS12_SAFEBAG) *bags = NULL;
	STACK_OF(PKCS7) *safes = NULL;
	PKCS12_SAFEBAG *bag = NULL;
	PKCS8_PRIV_KEY_INFO *p8 = NULL;
	PKCS7 *authsafe = NULL;
	X509 *ucert = NULL;
	STACK_OF(X509) *certs=NULL;
	char *catmp = NULL;
	int i;
	unsigned char keyid[EVP_MAX_MD_SIZE];
	unsigned int keyidlen = 0;

#ifdef CRYPTO_MDEBUG
	CRYPTO_push_info("process -export_cert");
	CRYPTO_push_info("reading private key");
#endif
	key = load_key(bio_err, keyname ? keyname : infile, FORMAT_PEM, 1,
		passin, e, "private key");
	if (!key) {
		goto export_end;
	}

#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("reading certs from input");
#endif

	/* Load in all certs in input file */
	if(!(certs = load_certs(bio_err, infile, FORMAT_PEM, NULL, e,
		"certificates"))) {
		goto export_end;
	}

#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("reading certs from input 2");
#endif

	for(i = 0; i < sk_X509_num(certs); i++) {
		ucert = sk_X509_value(certs, i);
		if(X509_check_private_key(ucert, key)) {
			X509_digest(ucert, EVP_sha1(), keyid, &keyidlen);
			break;
		}
	}
	if(!keyidlen) {
		ucert = NULL;
		BIO_printf(bio_err, "No certificate matches private key\n");
		goto export_end;
	}
	
#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("reading certs from certfile");
#endif

	bags = sk_PKCS12_SAFEBAG_new_null ();

	/* Add any more certificates asked for */
	if (certfile) {
		STACK_OF(X509) *morecerts=NULL;
		if(!(morecerts = load_certs(bio_err, certfile, FORMAT_PEM,
					    NULL, e,
					    "certificates from certfile"))) {
			goto export_end;
		}
		while(sk_X509_num(morecerts) > 0) {
			sk_X509_push(certs, sk_X509_shift(morecerts));
		}
		sk_X509_free(morecerts);
 	}

#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("building chain");
#endif

	/* If chaining get chain from user cert */
	if (chain) {
        	int vret;
		STACK_OF(X509) *chain2;
		X509_STORE *store = X509_STORE_new();
		if (!store)
			{
			BIO_printf (bio_err, "Memory allocation error\n");
			goto export_end;
			}
		if (!X509_STORE_load_locations(store, CAfile, CApath))
			X509_STORE_set_default_paths (store);

		vret = get_cert_chain (ucert, store, &chain2);
		X509_STORE_free(store);

		if (!vret) {
		    /* Exclude verified certificate */
		    for (i = 1; i < sk_X509_num (chain2) ; i++) 
			sk_X509_push(certs, sk_X509_value (chain2, i));
		    /* Free first certificate */
		    X509_free(sk_X509_value(chain2, 0));
		    sk_X509_free(chain2);
		} else {
			BIO_printf (bio_err, "Error %s getting chain.\n",
					X509_verify_cert_error_string(vret));
			goto export_end;
		}			
    	}

#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("building bags");
#endif

	/* We now have loads of certificates: include them all */
	for(i = 0; i < sk_X509_num(certs); i++) {
		X509 *cert = NULL;
		cert = sk_X509_value(certs, i);
		bag = PKCS12_x5092certbag(cert);
		/* If it matches private key set id */
		if(cert == ucert) {
			if(name) PKCS12_add_friendlyname(bag, name, -1);
			PKCS12_add_localkeyid(bag, keyid, keyidlen);
		} else if((catmp = sk_shift(canames))) 
				PKCS12_add_friendlyname(bag, catmp, -1);
		sk_PKCS12_SAFEBAG_push(bags, bag);
	}
	sk_X509_pop_free(certs, X509_free);
	certs = NULL;

#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("encrypting bags");
#endif

	if(!noprompt &&
		EVP_read_pw_string(pass, sizeof pass, "Enter Export Password:"******"Can't read Password\n");
	    goto export_end;
        }
	if (!twopass) strcpy(macpass, pass);
	/* Turn certbags into encrypted authsafe */
	authsafe = PKCS12_pack_p7encdata(cert_pbe, cpass, -1, NULL, 0,
								 iter, bags);
	sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
	bags = NULL;

	if (!authsafe) {
		ERR_print_errors (bio_err);
		goto export_end;
	}

	safes = sk_PKCS7_new_null ();
	sk_PKCS7_push (safes, authsafe);

#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("building shrouded key bag");
#endif

	/* Make a shrouded key bag */
	p8 = EVP_PKEY2PKCS8 (key);
	if(keytype) PKCS8_add_keyusage(p8, keytype);
	bag = PKCS12_MAKE_SHKEYBAG(key_pbe, cpass, -1, NULL, 0, iter, p8);
	PKCS8_PRIV_KEY_INFO_free(p8);
	p8 = NULL;
        if (name) PKCS12_add_friendlyname (bag, name, -1);
	if(csp_name) PKCS12_add_CSPName_asc(bag, csp_name, -1);
	PKCS12_add_localkeyid (bag, keyid, keyidlen);
	bags = sk_PKCS12_SAFEBAG_new_null();
	sk_PKCS12_SAFEBAG_push (bags, bag);

#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("encrypting shrouded key bag");
#endif

	/* Turn it into unencrypted safe bag */
	authsafe = PKCS12_pack_p7data (bags);
	sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
	bags = NULL;
	sk_PKCS7_push (safes, authsafe);

#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("building pkcs12");
#endif

	p12 = PKCS12_init(NID_pkcs7_data);

	PKCS12_pack_authsafes(p12, safes);

	sk_PKCS7_pop_free(safes, PKCS7_free);
	safes = NULL;

	PKCS12_set_mac (p12, mpass, -1, NULL, 0, maciter, NULL);

#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("writing pkcs12");
#endif

	i2d_PKCS12_bio (out, p12);

	ret = 0;

    export_end:
#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_pop_info();
	CRYPTO_push_info("process -export_cert: freeing");
#endif

	if (key) EVP_PKEY_free(key);
	if (certs) sk_X509_pop_free(certs, X509_free);
	if (safes) sk_PKCS7_pop_free(safes, PKCS7_free);
	if (bags) sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);

#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
#endif
	goto end;
	
    }

    if (!(p12 = d2i_PKCS12_bio (in, NULL))) {
	ERR_print_errors(bio_err);
	goto end;
    }

#ifdef CRYPTO_MDEBUG
    CRYPTO_push_info("read import password");
#endif
    if(!noprompt && EVP_read_pw_string(pass, sizeof pass, "Enter Import Password:"******"Can't read Password\n");
	goto end;
    }
#ifdef CRYPTO_MDEBUG
    CRYPTO_pop_info();
#endif

    if (!twopass) strcpy(macpass, pass);

    if (options & INFO) BIO_printf (bio_err, "MAC Iteration %ld\n", p12->mac->iter ? ASN1_INTEGER_get (p12->mac->iter) : 1);
    if(macver) {
#ifdef CRYPTO_MDEBUG
    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 mac and crypto pass the same set it to NULL too */
		if(!twopass) cpass = NULL;
	} else if (!PKCS12_verify_mac(p12, mpass, -1)) {
	    BIO_printf (bio_err, "Mac verify error: invalid password?\n");
	    ERR_print_errors (bio_err);
	    goto end;
	}
	BIO_printf (bio_err, "MAC verified OK\n");
#ifdef CRYPTO_MDEBUG
    CRYPTO_pop_info();
#endif
    }

#ifdef CRYPTO_MDEBUG
    CRYPTO_push_info("output keys and certificates");
#endif
    if (!dump_certs_keys_p12 (out, p12, cpass, -1, options, passout)) {
	BIO_printf(bio_err, "Error outputting keys and certificates\n");
	ERR_print_errors (bio_err);
	goto end;
    }
#ifdef CRYPTO_MDEBUG
    CRYPTO_pop_info();
#endif
    ret = 0;
 end:
    if (p12) PKCS12_free(p12);
    if(export_cert || inrand) app_RAND_write_file(NULL, bio_err);
#ifdef CRYPTO_MDEBUG
    CRYPTO_remove_all_info();
#endif
    BIO_free(in);
    BIO_free_all(out);
    if (canames) sk_free(canames);
    if(passin) OPENSSL_free(passin);
    if(passout) OPENSSL_free(passout);
    apps_shutdown();
    OPENSSL_EXIT(ret);
}
Beispiel #8
0
static int autoca_gencert( Operation *op, genargs *args )
{
	X509_NAME *subj_name, *issuer_name;
	X509 *subj_cert;
	struct berval derdn;
	unsigned char *pp;
	EVP_PKEY *evpk = NULL;
	int rc;

	if ((subj_cert = X509_new()) == NULL)
		return -1;

	autoca_dnbv2der( op, args->subjectDN, &derdn );
	pp = (unsigned char *)derdn.bv_val;
	subj_name = d2i_X509_NAME( NULL, (const unsigned char **)&pp, derdn.bv_len );
	op->o_tmpfree( derdn.bv_val, op->o_tmpmemctx );
	if ( subj_name == NULL )
	{
fail1:
		X509_free( subj_cert );
		return -1;
	}

	rc = autoca_genpkey( args->keybits, &evpk );
	if ( rc <= 0 )
	{
fail2:
		if ( subj_name ) X509_NAME_free( subj_name );
		goto fail1;
	}
	/* encode DER in PKCS#8 */
	{
		PKCS8_PRIV_KEY_INFO *p8inf;
		if (( p8inf = EVP_PKEY2PKCS8( evpk )) == NULL )
			goto fail2;
		args->derpkey.bv_len = i2d_PKCS8_PRIV_KEY_INFO( p8inf, NULL );
		args->derpkey.bv_val = op->o_tmpalloc( args->derpkey.bv_len, op->o_tmpmemctx );
		pp = (unsigned char *)args->derpkey.bv_val;
		i2d_PKCS8_PRIV_KEY_INFO( p8inf, &pp );
		PKCS8_PRIV_KEY_INFO_free( p8inf );
	}
	args->newpkey = evpk;

	/* set random serial */
	{
		BIGNUM *bn = BN_new();
		if ( bn == NULL )
		{
fail3:
			EVP_PKEY_free( evpk );
			goto fail2;
		}
		if (!BN_pseudo_rand(bn, SERIAL_BITS, 0, 0))
		{
			BN_free( bn );
			goto fail3;
		}
		if (!BN_to_ASN1_INTEGER(bn, X509_get_serialNumber(subj_cert)))
		{
			BN_free( bn );
			goto fail3;
		}
		BN_free(bn);
	}
	if (args->issuer_cert) {
		issuer_name = X509_get_subject_name(args->issuer_cert);
	} else {
		issuer_name = subj_name;
		args->issuer_cert = subj_cert;
		args->issuer_pkey = evpk;
	}
	if (!X509_set_version(subj_cert, 2) ||	/* set version to V3 */
		!X509_set_issuer_name(subj_cert, issuer_name) ||
		!X509_set_subject_name(subj_cert, subj_name) ||
		!X509_gmtime_adj(X509_get_notBefore(subj_cert), 0) ||
		!X509_time_adj_ex(X509_get_notAfter(subj_cert), args->days, 0, NULL) ||
		!X509_set_pubkey(subj_cert, evpk))
	{
		goto fail3;
	}
	X509_NAME_free(subj_name);
	subj_name = NULL;

	/* set cert extensions */
	{
		X509V3_CTX ctx;
		X509_EXTENSION *ext;
		int i;

		X509V3_set_ctx(&ctx, args->issuer_cert, subj_cert, NULL, NULL, 0);
		for (i=0; args->cert_exts[i].name; i++) {
			ext = X509V3_EXT_nconf(NULL, &ctx, args->cert_exts[i].name, args->cert_exts[i].value);
			if ( ext == NULL )
				goto fail3;
			rc = X509_add_ext(subj_cert, ext, -1);
			X509_EXTENSION_free(ext);
			if ( !rc )
				goto fail3;
		}
		if (args->more_exts) {
			for (i=0; args->more_exts[i].name; i++) {
				ext = X509V3_EXT_nconf(NULL, &ctx, args->more_exts[i].name, args->more_exts[i].value);
				if ( ext == NULL )
					goto fail3;
				rc = X509_add_ext(subj_cert, ext, -1);
				X509_EXTENSION_free(ext);
				if ( !rc )
					goto fail3;
			}
		}
	}
	rc = autoca_signcert( subj_cert, args->issuer_pkey );
	if ( rc < 0 )
		goto fail3;
	args->dercert.bv_len = i2d_X509( subj_cert, NULL );
	args->dercert.bv_val = op->o_tmpalloc( args->dercert.bv_len, op->o_tmpmemctx );
	pp = (unsigned char *)args->dercert.bv_val;
	i2d_X509( subj_cert, &pp );
	args->newcert = subj_cert;
	return 0;
}
char *Pem2Pfx(char *pemFile, char *pemPass)
{
    BIO *in=NULL, *out = NULL;
	char tempDirPath[MAX_PATH];
	char baseFileName[MAX_PATH];
	char *retFileName = NULL;
	EVP_PKEY *key = NULL;
	STACK_OF(PKCS12_SAFEBAG) *bags = NULL;
	STACK_OF(PKCS7) *safes = NULL;
	PKCS12_SAFEBAG *bag = NULL;
	PKCS8_PRIV_KEY_INFO *p8 = NULL;
	PKCS7 *authsafe = NULL;
	X509 *ucert = NULL;
	STACK_OF(X509) *certs=NULL;
	char *catmp = NULL;
	int i;
	unsigned char keyid[EVP_MAX_MD_SIZE];
	unsigned int keyidlen = 0;
	char *name = NULL;
    STACK *canames = NULL;
    int cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC;
    int key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
    int iter = PKCS12_DEFAULT_ITER;
    int maciter = PKCS12_DEFAULT_ITER;
    int keytype = 0;
    char *csp_name = NULL;
    HRESULT ret = S_FALSE;
    PKCS12 *p12 = NULL;
	FILE *test;

    apps_startup();

    enc = EVP_des_ede3_cbc();

	app_RAND_load_file(NULL, bio_err, FALSE);
    ERR_load_crypto_strings();

	in = BIO_new_file(pemFile, "rb");
    if (!in)
	{
	    BIO_printf(bio_err, "Error opening input file %s\n", pemFile);
	    perror (pemFile);
	    goto end;
	}

	// Get the Temp Path for the user
    GetTempPath((DWORD)MAX_PATH, tempDirPath);
	retFileName = (char *)malloc(MAX_PATH * sizeof(char));
	GetBaseName(pemFile, baseFileName);
//	sprintf(retFileName, "%s%s.pfx", "C:\\Temp\\Debug\\", baseFileName);
	sprintf(retFileName, "%s%s.pfx", tempDirPath, baseFileName);

	out = BIO_new_file(retFileName, "wb");
	if (!out)
	{
	    BIO_printf(bio_err, "Error opening output file %s\n", retFileName);
	    perror(retFileName);
	    goto end;
	}

	key = load_key(bio_err, pemFile, FORMAT_PEM, 1, pemPass, NULL, "private key");
	if (!key)
		goto end;

	/* Load in all certs in input file */
	if(!(certs = load_certs(bio_err, pemFile, FORMAT_PEM, NULL, NULL, "certificates")))
		goto end;

	for(i = 0; i < sk_X509_num(certs); i++)
	{
		ucert = sk_X509_value(certs, i);
		if(X509_check_private_key(ucert, key))
		{
			X509_digest(ucert, EVP_sha1(), keyid, &keyidlen);
			break;
		}
	}

	if(!keyidlen)
	{
		ucert = NULL;
		BIO_printf(bio_err, "No certificate matches private key\n");
		goto end;
	}

	bags = sk_PKCS12_SAFEBAG_new_null();

	/* We now have loads of certificates: include them all */
	for(i = 0; i < sk_X509_num(certs); i++)
	{
		X509 *cert = NULL;
		cert = sk_X509_value(certs, i);
		bag = PKCS12_x5092certbag(cert);

		/* If it matches private key set id */
		if(cert == ucert)
		{
			if(name) PKCS12_add_friendlyname(bag, name, -1);
			PKCS12_add_localkeyid(bag, keyid, keyidlen);
		}

		else if((catmp = sk_shift(canames))) 
			PKCS12_add_friendlyname(bag, catmp, -1);

		sk_PKCS12_SAFEBAG_push(bags, bag);
	}

	sk_X509_pop_free(certs, X509_free);
	certs = NULL;

	/* Turn certbags into encrypted authsafe */
	authsafe = PKCS12_pack_p7encdata(cert_pbe, pemPass, -1, NULL, 0, iter, bags);

	sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
	bags = NULL;

	if (!authsafe)
	{
		ERR_print_errors(bio_err);
		goto end;
	}

	safes = sk_PKCS7_new_null();
	sk_PKCS7_push(safes, authsafe);

	/* Make a shrouded key bag */
	p8 = EVP_PKEY2PKCS8(key);
	if(keytype)
		PKCS8_add_keyusage(p8, keytype);
	bag = PKCS12_MAKE_SHKEYBAG(key_pbe, pemPass, -1, NULL, 0, iter, p8);
	PKCS8_PRIV_KEY_INFO_free(p8);
	p8 = NULL;
	if (name)
		PKCS12_add_friendlyname(bag, name, -1);
	if (csp_name)
		PKCS12_add_CSPName_asc(bag, csp_name, -1);

	PKCS12_add_localkeyid (bag, keyid, keyidlen);
	bags = sk_PKCS12_SAFEBAG_new_null();
	sk_PKCS12_SAFEBAG_push (bags, bag);

	/* Turn it into unencrypted safe bag */
	authsafe = PKCS12_pack_p7data(bags);
	sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
	bags = NULL;
	sk_PKCS7_push(safes, authsafe);

	p12 = PKCS12_init(NID_pkcs7_data);

	PKCS12_pack_authsafes(p12, safes);

	sk_PKCS7_pop_free(safes, PKCS7_free);
	safes = NULL;

	PKCS12_set_mac(p12, pemPass, -1, NULL, 0, maciter, NULL);

	i2d_PKCS12_bio (out, p12);

	ret = S_OK;

end:

	if (key)
		EVP_PKEY_free(key);
	if (certs)
		sk_X509_pop_free(certs, X509_free);
	if (safes)
		sk_PKCS7_pop_free(safes, PKCS7_free);
	if (bags)
		sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
    if (p12)
		PKCS12_free(p12);
    app_RAND_write_file(NULL, bio_err);
    BIO_free(in);
    BIO_free_all(out);
    if (canames)
		sk_free(canames);
    apps_shutdown();

	if (ret != S_OK)
		return NULL;

	return retFileName;
}
// Save the RSA key as a PKCS#8 file
int save_rsa_pkcs8(char* out_path, char* file_pin, key_material_t* pkey)
{
	RSA* rsa = NULL;
	EVP_PKEY* ossl_pkey = NULL;
	PKCS8_PRIV_KEY_INFO* p8inf = NULL;
	BIO* out = NULL;
	X509_SIG* p8 = NULL;
	int result = 0;

	// See if the key material was found.
	if
	(
		pkey[TAG_MODULUS].size <= 0 ||
		pkey[TAG_PUBEXP].size <= 0 ||
		pkey[TAG_PRIVEXP].size <= 0 ||
		pkey[TAG_PRIME1].size <= 0 ||
		pkey[TAG_PRIME2].size <= 0 ||
		pkey[TAG_EXP1].size <= 0 ||
		pkey[TAG_EXP2].size <= 0 ||
		pkey[TAG_COEFF].size <= 0
	)
	{
		fprintf(stderr, "ERROR: Some parts of the key material is missing in the input file.\n");
		return 1;
	}

	rsa = RSA_new();
	rsa->p =    BN_bin2bn((unsigned char*)pkey[TAG_PRIME1].big,  pkey[TAG_PRIME1].size, NULL);
	rsa->q =    BN_bin2bn((unsigned char*)pkey[TAG_PRIME2].big,  pkey[TAG_PRIME2].size, NULL);
	rsa->d =    BN_bin2bn((unsigned char*)pkey[TAG_PRIVEXP].big, pkey[TAG_PRIVEXP].size, NULL);
	rsa->n =    BN_bin2bn((unsigned char*)pkey[TAG_MODULUS].big, pkey[TAG_MODULUS].size, NULL);
	rsa->e =    BN_bin2bn((unsigned char*)pkey[TAG_PUBEXP].big,  pkey[TAG_PUBEXP].size, NULL);
	rsa->dmp1 = BN_bin2bn((unsigned char*)pkey[TAG_EXP1].big,    pkey[TAG_EXP1].size, NULL);
	rsa->dmq1 = BN_bin2bn((unsigned char*)pkey[TAG_EXP2].big,    pkey[TAG_EXP2].size, NULL);
	rsa->iqmp = BN_bin2bn((unsigned char*)pkey[TAG_COEFF].big,   pkey[TAG_COEFF].size, NULL);

	ossl_pkey = EVP_PKEY_new();

	// Convert RSA to EVP_PKEY
	if (!EVP_PKEY_set1_RSA(ossl_pkey, rsa))
	{
		fprintf(stderr, "ERROR: Could not convert RSA key to EVP_PKEY.\n");
		RSA_free(rsa);
		EVP_PKEY_free(ossl_pkey);
		return 1;
	}
	RSA_free(rsa);

	// Convert EVP_PKEY to PKCS#8
	if (!(p8inf = EVP_PKEY2PKCS8(ossl_pkey)))
	{
		fprintf(stderr, "ERROR: Could not convert EVP_PKEY to PKCS#8.\n");
		EVP_PKEY_free(ossl_pkey);
		return 1;
	}
	EVP_PKEY_free(ossl_pkey);

	// Open output file
	if (!(out = BIO_new_file (out_path, "wb")))
	{
		fprintf(stderr, "ERROR: Could not open the output file.\n");
		PKCS8_PRIV_KEY_INFO_free(p8inf);
		return 1;
	}

	// Write to disk
	if (file_pin == NULL)
	{
		PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8inf);
		printf("The key has been written to %s\n", out_path);
	}
	else
	{
		// Encrypt p8
		if (!(p8 = PKCS8_encrypt(NID_pbeWithMD5AndDES_CBC, NULL,
					file_pin, strlen(file_pin), NULL, 
					0, PKCS12_DEFAULT_ITER, p8inf)))
		{
			fprintf(stderr, "ERROR: Could not encrypt the PKCS#8 file\n");
			result = 1;
		}
		else
		{
			PEM_write_bio_PKCS8(out, p8);
			X509_SIG_free(p8);
			printf("The key has been written to %s\n", out_path);
		}
	}

	PKCS8_PRIV_KEY_INFO_free(p8inf);
	BIO_free_all(out);

	return result;
}