Beispiel #1
2
/*
This function take a user certificate and a private key in x509 format and
convert it into pkcs12 format. This function returns -1 if a problem occurs, 0 otherwise
*/
int convert_x509_to_p12(char *privkey, char *clicert, char *p12cert)
{
	X509      *cert;
        PKCS12    *p12;
        EVP_PKEY  *cert_privkey;
        FILE      *certfile, *keyfile, *p12file;
        int       bytes = 0;

	OpenSSL_add_all_algorithms();
        ERR_load_crypto_strings();

        /* Read the private key file */
        if ((cert_privkey = EVP_PKEY_new()) == NULL){
                printf("Error creating EVP_PKEY structure.\n");
		return -1;
	}
        if (! (keyfile = fopen(privkey, "r"))){
                printf("Error cant read certificate private key file.\n");
		return -1;
	}
        if (! (cert_privkey = PEM_read_PrivateKey(keyfile, NULL, NULL, NULL))){
                printf("Error loading certificate private key content.\n");
		return -1;
	}
        fclose(keyfile);

        /* Read the user certificate */
        if (! (certfile = fopen(clicert, "r"))){
                printf("Error cant read certificate file.\n");
		return -1;
	}
        if (! (cert = PEM_read_X509(certfile, NULL, NULL, NULL))){
                printf("Error loading cert into memory.\n");
		return -1;
	}
        fclose(certfile);

        /* Generate the p12 certificate */
        if ((p12 = PKCS12_new()) == NULL){
                printf("Error creating PKCS12 structure.\n");
		return -1;}
        p12 = PKCS12_create(NULL, NULL, cert_privkey, cert, NULL, 0, 0, 0, 0, 0);
        if ( p12 == NULL){
                printf("Error generating a valid PKCS12 certificate.\n");
		return -1;
	}
        if (! (p12file = fopen(p12cert, "w"))){
                printf("Error cant open pkcs12 certificate file for writing.\n");
		return -1;
	}
	bytes = i2d_PKCS12_fp(p12file, p12);
        if (bytes <= 0){
                printf("Error writing PKCS12 certificate.\n");
		return -1;
	}
        fclose(p12file);
        PKCS12_free(p12);
	X509_free(cert);
	EVP_PKEY_free(cert_privkey);

	return 0;
}
/*
 * 	Pass the key-size and the password and this function returns
 * 	the PKCS12 structure as a stream.
 */
PKCS12* create_PKCS12_stream(int keysize, const char *password)
{
     EVP_PKEY *privkey = NULL;
     X509 *x509_cert = NULL;
     STACK_OF(X509) *cacertstack = NULL;
     PKCS12 *pkcs12bundle = NULL;
     
     if(!keysize || !password)
     {
          fprintf(stderr,"Invalid key-size and/or password.\n");
          return NULL;
     }
     if(keysize > MAX_KEY_SIZE)
     {
          fprintf(stderr,"Limit the keysize to 4096 bits.\n");
          return NULL;
     }
     
     init_openssl();
     
     privkey = create_rsa_key(keysize);
     if(privkey == NULL)
     {
          return (PKCS12*)free_openssl_resources(privkey, x509_cert, cacertstack);
     }
     fprintf(stdout,"Successfully created rsa key.\n");
     
     x509_cert = create_x509_cert(privkey);
     if(x509_cert == NULL)
     {
          return (PKCS12*)free_openssl_resources(privkey, x509_cert, cacertstack);
     }
     fprintf(stdout,"Successfully created x509 certificate.\n");
     
     cacertstack = create_ca_cert_stack(x509_cert);
     if(cacertstack == NULL)
     {
          return (PKCS12*)free_openssl_resources(privkey, x509_cert, cacertstack);
     }
     fprintf(stdout,"Successfully created stack-of-x509.\n");
     
     if ((pkcs12bundle = PKCS12_new()) == NULL)
     {
          fprintf(stderr,"PKCS12_new failed.\n");
          return (PKCS12*)free_openssl_resources(privkey, x509_cert, cacertstack);
     }
	pkcs12bundle = PKCS12_create(
                         (char*)password,	// certbundle access password
                         "thali",	// friendly certname
                         privkey,	// the certificate private key
                         x509_cert,	// the main certificate
                         cacertstack,	// stack of CA cert chain
                         0,	// int nid_key (default 3DES)
                         0,	// int nid_cert (40bitRC2)
                         0,	// int iter (default 2048)
                         0,	// int mac_iter (default 1)
                         0	// int keytype (default no flag)
                         );
     if (pkcs12bundle == NULL)
     {
          fprintf(stderr,"PKCS12_create failed.\n");
          return (PKCS12*)free_openssl_resources(privkey, x509_cert, cacertstack);
     }
     fprintf(stdout,"Successfully created pkcs12 bundle.\n");
     
     free_openssl_resources(privkey, x509_cert, cacertstack);
     
     return pkcs12bundle; //TODO: Make this a stream (char *)
}
static VALUE
ossl_pkcs12_s_create(int argc, VALUE *argv, VALUE self)
{
    VALUE pass, name, pkey, cert, ca;
    VALUE obj;
    char *passphrase, *friendlyname;
    EVP_PKEY *key;
    X509 *x509;
    STACK_OF(X509) *x509s;
    PKCS12 *p12;
    
    rb_scan_args(argc, argv, "41", &pass, &name, &pkey, &cert, &ca);
    passphrase = NIL_P(pass) ? NULL : StringValuePtr(pass);
    friendlyname = NIL_P(name) ? NULL : StringValuePtr(name);
    key = GetPKeyPtr(pkey);
    x509 = GetX509CertPtr(cert);
    x509s = NIL_P(ca) ? NULL : ossl_x509_ary2sk(ca);
    p12 = PKCS12_create(passphrase, friendlyname, key, x509, x509s,
                        0, 0, 0, 0, 0);
    sk_X509_pop_free(x509s, X509_free);
    if(!p12) ossl_raise(ePKCS12Error, NULL);
    WrapPKCS12(cPKCS12, obj, p12);

    return obj;
}
Beispiel #4
0
void pki_pkcs12::writePKCS12(const QString fname)
{
	Passwd pass;
	pass_info p(XCA_TITLE, tr("Please enter the password to encrypt the PKCS#12 file"));
	if (cert == NULL || key == NULL) {
		my_error(tr("No key or no Cert and no pkcs12"));
	}

	FILE *fp = fopen(QString2filename(fname), "wb");
	if (fp != NULL) {
		if (PwDialog::execute(&p, &pass, true) != 1) {
			fclose(fp);
			return;
		}
		PKCS12 *pkcs12 = PKCS12_create(pass.data(),
			getIntName().toUtf8().data(),
			key->decryptKey(),
			cert->getCert(), certstack, 0, 0, 0, 0, 0);
		i2d_PKCS12_fp(fp, pkcs12);
		fclose (fp);
		openssl_error();
		PKCS12_free(pkcs12);
	}
	else fopen_error(fname);
}
Beispiel #5
0
static LUA_FUNCTION(openssl_pkcs12_export)
{
  X509 * cert = CHECK_OBJECT(1, X509, "openssl.x509");
  EVP_PKEY *priv_key = CHECK_OBJECT(2, EVP_PKEY, "openssl.evp_pkey");
  char * pass = (char*)luaL_checkstring(L, 3);
  int top = lua_gettop(L);

  BIO * bio_out = NULL;
  PKCS12 * p12 = NULL;
  const char * friendly_name = NULL;
  STACK_OF(X509) *ca = NULL;
  int ret = 0;

  luaL_argcheck(L, openssl_pkey_is_private(priv_key), 2, "must be private key");

  if (top > 3)
  {
    if (lua_isstring(L, 4))
      friendly_name = lua_tostring(L, 4);
    else if (lua_isuserdata(L, 4))
      ca = CHECK_OBJECT(4, STACK_OF(X509), "openssl.stack_of_x509");
    else
      luaL_argerror(L, 4, "must be string as friendly_name or openssl.stack_of_x509 object as cacets");

    if (top > 4)
      ca = CHECK_OBJECT(5, STACK_OF(X509), "openssl.stack_of_x509");
  }

  if (cert && !X509_check_private_key(cert, priv_key))
  {
    luaL_error(L, "private key does not correspond to cert");
  }

  /* end parse extra config */

  /*PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert, STACK_OF(X509) *ca,
                                     int nid_key, int nid_cert, int iter, int mac_iter, int keytype);*/

  p12 = PKCS12_create(pass, (char*)friendly_name, priv_key, cert, ca, 0, 0, 0, 0, 0);
  if (!p12)
    luaL_error(L, "PKCS12_careate failed,pleases get more error info");

  bio_out = BIO_new(BIO_s_mem());
  if (i2d_PKCS12_bio(bio_out, p12))
  {
    BUF_MEM *bio_buf;

    BIO_get_mem_ptr(bio_out, &bio_buf);
    lua_pushlstring(L, bio_buf->data, bio_buf->length);
    ret = 1;
  }
  BIO_free(bio_out);
  PKCS12_free(p12);

  return ret;
}
Beispiel #6
0
int __fastcall util_to_p12(struct util_cert cert, char *password, char** data)
{
	PKCS12 *p12;
	int len;
	p12 = PKCS12_create(password, "Certificate", cert.pkey, cert.x509, NULL, 0, 0, 0, 0, 0);
	*data = NULL;
	len = i2d_PKCS12(p12, (unsigned char**)data);
	PKCS12_free(p12);
	return len;
}
Beispiel #7
0
/*
 * call-seq:
 *    PKCS12.create(pass, name, key, cert [, ca, [, key_pbe [, cert_pbe [, key_iter [, mac_iter [, keytype]]]]]])
 *
 * === Parameters
 * * +pass+ - string
 * * +name+ - A string describing the key.
 * * +key+ - Any PKey.
 * * +cert+ - A X509::Certificate.
 * * * The public_key portion of the certificate must contain a valid public key.
 * * * The not_before and not_after fields must be filled in.
 * * +ca+ - An optional array of X509::Certificate's.
 * * +key_pbe+ - string
 * * +cert_pbe+ - string
 * * +key_iter+ - integer
 * * +mac_iter+ - integer
 * * +keytype+ - An integer representing an MSIE specific extension.
 *
 * Any optional arguments may be supplied as nil to preserve the OpenSSL defaults.
 *
 * See the OpenSSL documentation for PKCS12_create().
 */
static VALUE
ossl_pkcs12_s_create(int argc, VALUE *argv, VALUE self)
{
    VALUE pass, name, pkey, cert, ca, key_nid, cert_nid, key_iter, mac_iter, keytype;
    VALUE obj;
    char *passphrase, *friendlyname;
    EVP_PKEY *key;
    X509 *x509;
    STACK_OF(X509) *x509s;
    int nkey = 0, ncert = 0, kiter = 0, miter = 0, ktype = 0;
    PKCS12 *p12;

    rb_scan_args(argc, argv, "46", &pass, &name, &pkey, &cert, &ca, &key_nid, &cert_nid, &key_iter, &mac_iter, &keytype);
    passphrase = NIL_P(pass) ? NULL : StringValuePtr(pass);
    friendlyname = NIL_P(name) ? NULL : StringValuePtr(name);
    key = GetPKeyPtr(pkey);
    x509 = GetX509CertPtr(cert);
    x509s = NIL_P(ca) ? NULL : ossl_x509_ary2sk(ca);
/* TODO: make a VALUE to nid function */
    if (!NIL_P(key_nid)) {
        if ((nkey = OBJ_txt2nid(StringValuePtr(key_nid))) == NID_undef)
            rb_raise(rb_eArgError, "Unknown PBE algorithm %s", StringValuePtr(key_nid));
    }
    if (!NIL_P(cert_nid)) {
        if ((ncert = OBJ_txt2nid(StringValuePtr(cert_nid))) == NID_undef)
            rb_raise(rb_eArgError, "Unknown PBE algorithm %s", StringValuePtr(cert_nid));
    }
    if (!NIL_P(key_iter))
        kiter = NUM2INT(key_iter);
    if (!NIL_P(mac_iter))
        miter = NUM2INT(mac_iter);
    if (!NIL_P(keytype))
        ktype = NUM2INT(keytype);

    p12 = PKCS12_create(passphrase, friendlyname, key, x509, x509s,
                        nkey, ncert, kiter, miter, ktype);
    sk_X509_pop_free(x509s, X509_free);
    if(!p12) ossl_raise(ePKCS12Error, NULL);
    WrapPKCS12(cPKCS12, obj, p12);

    ossl_pkcs12_set_key(obj, pkey);
    ossl_pkcs12_set_cert(obj, cert);
    ossl_pkcs12_set_ca_certs(obj, ca);

    return obj;
}
Beispiel #8
0
void pki_pkcs12::writePKCS12(const QString fname)
{
	char pass[MAX_PASS_LENGTH];
	pass_info p(XCA_TITLE, tr("Please enter the password to encrypt the PKCS#12 file"));
	if (cert == NULL || key == NULL) {
		my_error(tr("No key or no Cert and no pkcs12"));
	}

	FILE *fp = fopen(QString2filename(fname), "wb");
	if (fp != NULL) {
		passcb(pass, MAX_PASS_LENGTH, 0, &p);
		PKCS12 *pkcs12 = PKCS12_create(pass,
			getIntName().toUtf8().data(),
			key->decryptKey(),
			cert->getCert(), certstack, 0, 0, 0, 0, 0);
		i2d_PKCS12_fp(fp, pkcs12);
		openssl_error();
		fclose (fp);
		PKCS12_free(pkcs12);
	}
	else fopen_error(fname);
}
Beispiel #9
0
int main(int argc, char **argv)
{
	FILE *fp;
	EVP_PKEY *pkey;
	X509 *cert;
	PKCS12 *p12;
	if (argc != 5) {
		fprintf(stderr, "Usage: pkwrite infile password name p12file\n");
		exit(1);
	}
	SSLeay_add_all_algorithms();
	ERR_load_crypto_strings();
	if (!(fp = fopen(argv[1], "r"))) {
		fprintf(stderr, "Error opening file %s\n", argv[1]);
		exit(1);
	}
	cert = PEM_read_X509(fp, NULL, NULL, NULL);
	rewind(fp);
	pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
	fclose(fp);
	p12 = PKCS12_create(argv[2], argv[3], pkey, cert, NULL, 0,0,0,0,0);
	if(!p12) {
		fprintf(stderr, "Error creating PKCS#12 structure\n");
		ERR_print_errors_fp(stderr);
		exit(1);
	}
	if (!(fp = fopen(argv[4], "wb"))) {
		fprintf(stderr, "Error opening file %s\n", argv[1]);
		ERR_print_errors_fp(stderr);
		exit(1);
	}
	i2d_PKCS12_fp(fp, p12);
	PKCS12_free(p12);
	fclose(fp);
	return 0;
}
Beispiel #10
0
void openssl_pkcs12_cert()
{
	FILE *tmpfile;
	PKCS12 *pkcs12s;
	EVP_PKEY *certprk;
	X509 *cscert, *cacert;
	STACK_OF(X509) * cacerts;

	OpenSSL_add_all_algorithms();
	ERR_load_crypto_strings();

	certprk = EVP_PKEY_new();
	tmpfile = fopen(PKEYF, "r");
	certprk = PEM_read_PrivateKey(tmpfile, NULL, NULL, NULL);
	fclose(tmpfile);

	tmpfile = fopen(PCERTF, "r");
	cscert = PEM_read_X509(tmpfile, NULL, NULL, NULL);
	fclose(tmpfile);

	tmpfile = fopen(RCERTF, "r");
	cacert = PEM_read_X509(tmpfile, NULL, NULL, NULL);
	fclose(tmpfile);

	pkcs12s = PKCS12_new();
	cacerts = sk_X509_new_null();
	sk_X509_push(cacerts, cacert);
	pkcs12s = PKCS12_create("beike2012", "mypkcs12", certprk, cscert,
							cacerts, 0, 0, 0, 0, 0);
	tmpfile = fopen(PKCS12F, "w");
	if (i2d_PKCS12_fp(tmpfile, pkcs12s) <= 0)
		openssl_error_show("i2d_PKCS12_fp", 1);
	fclose(tmpfile);
	sk_X509_free(cacerts);
	PKCS12_free(pkcs12s);
}
Beispiel #11
0
struct CertKeyPair generateCertKeyPair() {
    BIO *bio_err;
    X509 *x509 = NULL;
    EVP_PKEY *pkey = NULL;
    PKCS12 *p12 = NULL;
   
    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
    bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
    
    SSLeay_add_all_algorithms();
    ERR_load_crypto_strings();
    
    mkcert(&x509, &pkey, NUM_BITS, SERIAL, NUM_YEARS);

    p12 = PKCS12_create("limelight", "GameStream", pkey, x509, NULL, 0, 0, 0, 0, 0);
    if (p12 == NULL) {
        printf("Error generating a valid PKCS12 certificate.\n");
    }

    // Debug Print statements
    //RSA_print_fp(stdout, pkey->pkey.rsa, 0);
    //X509_print_fp(stdout, x509);
    //PEM_write_PUBKEY(stdout, pkey);
    //PEM_write_PrivateKey(stdout, pkey, NULL, NULL, 0, NULL, NULL);
    //PEM_write_X509(stdout, x509);
    
#ifndef OPENSSL_NO_ENGINE
    ENGINE_cleanup();
#endif
    CRYPTO_cleanup_all_ex_data();
    
    CRYPTO_mem_leaks(bio_err);
    BIO_free(bio_err);
    
    return (CertKeyPair){x509, pkey, p12};
}
Beispiel #12
0
/* ChangePasswordPKCS12() returns:
 * -1 Wrong password
 * 0  Changing password failed for unknown reason
 * 1  Password changed successfully
 */
int ChangePasswordPKCS12(HWND hwndDlg)
{
  char keyfile[MAX_PATH];
  char oldpsw[50];
  char newpsw[50];
  WCHAR oldpsw_unicode[50];
  WCHAR newpsw_unicode[50];
  FILE *fp;

  EVP_PKEY *privkey;
  X509 *cert;
  STACK_OF(X509) *ca = NULL;
  PKCS12 *p12;
  PKCS12 *new_p12;
  char *alias;

  /* Get filename, old_psw and new_psw from Dialog */
  GetDlgItemText(hwndDlg, TEXT_KEYFILE, keyfile, sizeof(keyfile) - 1); 
  GetDlgItemTextW(hwndDlg, EDIT_PSW_CURRENT, oldpsw_unicode, sizeof(oldpsw_unicode)/2 - 1); 
  GetDlgItemTextW(hwndDlg, EDIT_PSW_NEW, newpsw_unicode, sizeof(newpsw_unicode)/2 - 1); 

  /* Convert Unicode to ASCII (CP850) */
  ConvertUnicode2Ascii(oldpsw_unicode, oldpsw, sizeof(oldpsw));
  if (!ConvertUnicode2Ascii(newpsw_unicode, newpsw, sizeof(newpsw)))
    {
      ShowLocalizedMsg(GUI_NAME, ERR_INVALID_CHARS_IN_PSW, "");
      return(-1);
    }

  /* Load the PKCS #12 file */
  if (!(fp = fopen(keyfile, "rb")))
    {
      /* error opening file */
      ShowLocalizedMsg(GUI_NAME, ERR_OPEN_PRIVATE_KEY_FILE, keyfile);
      return(0);
    }
  p12 = d2i_PKCS12_fp(fp, NULL);
  fclose (fp);
  if (!p12) 
    {
      /* error reading PKCS #12 */
      ShowLocalizedMsg(GUI_NAME, ERR_READ_PKCS12, keyfile);
      return(0);
    }

  /* Parse the PKCS #12 file */
  if (!PKCS12_parse(p12, oldpsw, &privkey, &cert, &ca))
    {
      /* old password incorrect */
      ShowLocalizedMsg(GUI_NAME, ERR_OLD_PWD_INCORRECT, ""); 
      PKCS12_free(p12);
      return(-1);
    }

  /* Free old PKCS12 object */
  PKCS12_free(p12);

  /* Get FriendlyName of old cert */
  alias = X509_alias_get0(cert, NULL);

  /* Create new PKCS12 object */
  p12 = PKCS12_create(newpsw, alias, privkey, cert, ca, 0,0,0,0,0);
  if (!p12)
    {
      /* create failed */
      //ShowMsg(GUI_NAME, ERR_error_string(ERR_peek_last_error(), NULL));
      ShowLocalizedMsg(GUI_NAME, ERR_CREATE_PKCS12, "");
      return(0);
    }

  /* Free old key, cert and ca */
  EVP_PKEY_free(privkey);
  X509_free(cert);
  sk_X509_pop_free(ca, X509_free);

  /* Open keyfile for writing */
  if (!(fp = fopen(keyfile, "wb")))
    {
      ShowLocalizedMsg(GUI_NAME, ERR_OPEN_WRITE_KEY, keyfile);
      PKCS12_free(p12);
      return(0);
    }

  /* Write new key to file */
  i2d_PKCS12_fp(fp, p12);

  PKCS12_free(p12);
  fclose(fp);
  /* signal success to user */
  ShowLocalizedMsg(GUI_NAME, INFO_PWD_CHANGED, "");

  return(1);
}
Beispiel #13
0
int
pkcs12_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;
	int add_lmk = 0;
	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;
	int key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
	int ret = 1;
	int macver = 1;
	int noprompt = 0;
	STACK_OF(OPENSSL_STRING) * canames = NULL;
	char *cpass = NULL, *mpass = NULL;
	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

	signal(SIGPIPE, SIG_IGN);

	cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC;

	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();
			else if (!strcmp(*args, "-des3"))
				enc = EVP_des_ede3_cbc();
#ifndef OPENSSL_NO_IDEA
			else if (!strcmp(*args, "-idea"))
				enc = EVP_idea_cbc();
#endif
#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"))
				maciter = PKCS12_DEFAULT_ITER;
			else if (!strcmp(*args, "-nomaciter"))
				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 (!set_pbe(bio_err, &cert_pbe, *++args))
					badarg = 1;
			} else if (!strcmp(*args, "-keypbe")) {
				if (!set_pbe(bio_err, &key_pbe, *++args))
					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, "-LMK"))
				add_lmk = 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_OPENSSL_STRING_new_null();
					sk_OPENSSL_STRING_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;
#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;
		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_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:file:...\n");
		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");
		BIO_printf(bio_err, "-LMK          Add local machine keyset attribute to private key\n");
		goto end;
	}
#ifndef OPENSSL_NO_ENGINE
	e = setup_engine(bio_err, engine, 0);
#endif

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

	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;
	}
#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("write files");
#endif

	if (!outfile) {
		out = BIO_new_fp(stdout, BIO_NOCLOSE);
	} 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;
		X509 *ucert = NULL, *x = NULL;
		STACK_OF(X509) * certs = NULL;
		const EVP_MD *macmd = NULL;
		unsigned char *catmp = NULL;
		int i;

		if ((options & (NOCERTS | NOKEYS)) == (NOCERTS | NOKEYS)) {
			BIO_printf(bio_err, "Nothing to do!\n");
			goto export_end;
		}
		if (options & NOCERTS)
			chain = 0;

#ifdef CRYPTO_MDEBUG
		CRYPTO_push_info("process -export_cert");
		CRYPTO_push_info("reading private key");
#endif
		if (!(options & NOKEYS)) {
			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 (!(options & NOCERTS)) {
			certs = load_certs(bio_err, infile, FORMAT_PEM, NULL, e,
			    "certificates");
			if (!certs)
				goto export_end;

			if (key) {
				/* Look for matching private key */
				for (i = 0; i < sk_X509_num(certs); i++) {
					x = sk_X509_value(certs, i);
					if (X509_check_private_key(x, key)) {
						ucert = x;
						/* Zero keyid and alias */
						X509_keyid_set1(ucert, NULL, 0);
						X509_alias_set1(ucert, NULL, 0);
						/* Remove from list */
						(void) sk_X509_delete(certs, i);
						break;
					}
				}
				if (!ucert) {
					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 input 2");
#endif

		/* 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("reading certs from certfile");
#endif

#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 {
				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;
			}
		}
		/* Add any CA names */

		for (i = 0; i < sk_OPENSSL_STRING_num(canames); i++) {
			catmp = (unsigned char *) sk_OPENSSL_STRING_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);

		if (add_lmk && key)
			EVP_PKEY_add1_attr_by_NID(key, NID_LocalKeySet, 0, NULL, -1);

#ifdef CRYPTO_MDEBUG
		CRYPTO_pop_info();
		CRYPTO_push_info("reading password");
#endif

		if (!noprompt &&
		    EVP_read_pw_string(pass, sizeof pass, "Enter Export Password:"******"Can't read Password\n");
			goto export_end;
		}
		if (!twopass)
			strlcpy(macpass, pass, sizeof macpass);

#ifdef CRYPTO_MDEBUG
		CRYPTO_pop_info();
		CRYPTO_push_info("creating PKCS#12 structure");
#endif

		p12 = PKCS12_create(cpass, name, key, ucert, certs,
		    key_pbe, cert_pbe, iter, -1, keytype);

		if (!p12) {
			ERR_print_errors(bio_err);
			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, macmd);

#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 (ucert)
			X509_free(ucert);

#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)
		strlcpy(macpass, pass, sizeof macpass);

	if ((options & INFO) && p12->mac)
		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 (!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)) {
			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);
#ifdef CRYPTO_MDEBUG
	CRYPTO_remove_all_info();
#endif
	BIO_free(in);
	BIO_free_all(out);
	if (canames)
		sk_OPENSSL_STRING_free(canames);
	if (passin)
		free(passin);
	if (passout)
		free(passout);
	
	return (ret);
}
Beispiel #14
0
int pkcs12_main(int argc, char **argv)
{
    char *infile = NULL, *outfile = NULL, *keyname = NULL, *certfile = NULL;
    char *name = NULL, *csp_name = NULL;
    char pass[50], macpass[50];
    int export_cert = 0, options = 0, chain = 0, twopass = 0, keytype = 0;
    int iter = PKCS12_DEFAULT_ITER, maciter = PKCS12_DEFAULT_ITER;
# ifndef OPENSSL_NO_RC2
    int cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC;
# else
    int cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
# endif
    int key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
    int ret = 1, macver = 1, noprompt = 0, add_lmk = 0;
    char *passinarg = NULL, *passoutarg = NULL, *passarg = NULL;
    char *passin = NULL, *passout = NULL, *inrand = NULL, *macalg = NULL;
    char *cpass = NULL, *mpass = NULL, *CApath = NULL, *CAfile = NULL;
    char *prog;
    ENGINE *e = NULL;
    BIO *in = NULL, *out = NULL;
    PKCS12 *p12 = NULL;
    STACK_OF(OPENSSL_STRING) *canames = NULL;
    const EVP_CIPHER *enc = EVP_des_ede3_cbc();
    OPTION_CHOICE o;

    prog = opt_init(argc, argv, pkcs12_options);
    while ((o = opt_next()) != OPT_EOF) {
        switch (o) {
        case OPT_EOF:
        case OPT_ERR:
 opthelp:
            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
            goto end;
        case OPT_HELP:
            opt_help(pkcs12_options);
            ret = 0;
            goto end;
        case OPT_NOKEYS:
            options |= NOKEYS;
            break;
        case OPT_KEYEX:
            keytype = KEY_EX;
            break;
        case OPT_KEYSIG:
            keytype = KEY_SIG;
            break;
        case OPT_NOCERTS:
            options |= NOCERTS;
            break;
        case OPT_CLCERTS:
            options |= CLCERTS;
            break;
        case OPT_CACERTS:
            options |= CACERTS;
            break;
        case OPT_NOOUT:
            options |= (NOKEYS | NOCERTS);
            break;
        case OPT_INFO:
            options |= INFO;
            break;
        case OPT_CHAIN:
            chain = 1;
            break;
        case OPT_TWOPASS:
            twopass = 1;
            break;
        case OPT_NOMACVER:
            macver = 0;
            break;
        case OPT_DESCERT:
            cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
            break;
        case OPT_EXPORT:
            export_cert = 1;
            break;
        case OPT_CIPHER:
            if (!opt_cipher(opt_unknown(), &enc))
                goto opthelp;
            break;
        case OPT_NOITER:
            iter = 1;
            break;
        case OPT_MACITER:
            maciter = PKCS12_DEFAULT_ITER;
            break;
        case OPT_NOMACITER:
            maciter = 1;
            break;
        case OPT_NOMAC:
            maciter = -1;
            break;
        case OPT_MACALG:
            macalg = opt_arg();
            break;
        case OPT_NODES:
            enc = NULL;
            break;
        case OPT_CERTPBE:
            if (!set_pbe(&cert_pbe, opt_arg()))
                goto opthelp;
            break;
        case OPT_KEYPBE:
            if (!set_pbe(&key_pbe, opt_arg()))
                goto opthelp;
            break;
        case OPT_RAND:
            inrand = opt_arg();
            break;
        case OPT_INKEY:
            keyname = opt_arg();
            break;
        case OPT_CERTFILE:
            certfile = opt_arg();
            break;
        case OPT_NAME:
            name = opt_arg();
            break;
        case OPT_LMK:
            add_lmk = 1;
            break;
        case OPT_CSP:
            csp_name = opt_arg();
            break;
        case OPT_CANAME:
            if (canames == NULL
                && (canames = sk_OPENSSL_STRING_new_null()) == NULL)
                goto end;
            sk_OPENSSL_STRING_push(canames, opt_arg());
            break;
        case OPT_IN:
            infile = opt_arg();
            break;
        case OPT_OUT:
            outfile = opt_arg();
            break;
        case OPT_PASSIN:
            passinarg = opt_arg();
            break;
        case OPT_PASSOUT:
            passoutarg = opt_arg();
            break;
        case OPT_PASSWORD:
            passarg = opt_arg();
            break;
        case OPT_CAPATH:
            CApath = opt_arg();
            break;
        case OPT_CAFILE:
            CAfile = opt_arg();
            break;
        case OPT_ENGINE:
            e = setup_engine(opt_arg(), 0);
            break;
        }
    }
    argc = opt_num_rest();
    argv = opt_rest();

    if (passarg) {
        if (export_cert)
            passoutarg = passarg;
        else
            passinarg = passarg;
    }

    if (!app_passwd(passinarg, passoutarg, &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, (inrand != NULL));
        if (inrand != NULL)
            BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
                       app_RAND_load_files(inrand));
    }

    in = bio_open_default(infile, "rb");
    if (in == NULL)
        goto end;

    out = bio_open_default(outfile, "wb");
    if (out == NULL)
        goto end;

    if (twopass) {
        if (EVP_read_pw_string
            (macpass, sizeof macpass, "Enter MAC Password:"******"Can't read Password\n");
            goto end;
        }
    }

    if (export_cert) {
        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;

        if ((options & (NOCERTS | NOKEYS)) == (NOCERTS | NOKEYS)) {
            BIO_printf(bio_err, "Nothing to do!\n");
            goto export_end;
        }

        if (options & NOCERTS)
            chain = 0;

        if (!(options & NOKEYS)) {
            key = load_key(keyname ? keyname : infile,
                           FORMAT_PEM, 1, passin, e, "private key");
            if (!key)
                goto export_end;
        }

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

            if (key) {
                /* Look for matching private key */
                for (i = 0; i < sk_X509_num(certs); i++) {
                    x = sk_X509_value(certs, i);
                    if (X509_check_private_key(x, key)) {
                        ucert = x;
                        /* Zero keyid and alias */
                        X509_keyid_set1(ucert, NULL, 0);
                        X509_alias_set1(ucert, NULL, 0);
                        /* Remove from list */
                        (void)sk_X509_delete(certs, i);
                        break;
                    }
                }
                if (!ucert) {
                    BIO_printf(bio_err,
                               "No certificate matches private key\n");
                    goto export_end;
                }
            }

        }

        /* Add any more certificates asked for */
        if (certfile) {
            STACK_OF(X509) *morecerts = NULL;
            if (!(morecerts = load_certs(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);
        }

        /* If chaining get chain from user cert */
        if (chain) {
            int vret;
            STACK_OF(X509) *chain2;
            X509_STORE *store;
            if (!(store = setup_verify(CAfile, CApath)))
                goto export_end;

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

        /* Add any CA names */

        for (i = 0; i < sk_OPENSSL_STRING_num(canames); i++) {
            catmp = (unsigned char *)sk_OPENSSL_STRING_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);

        if (add_lmk && key)
            EVP_PKEY_add1_attr_by_NID(key, NID_LocalKeySet, 0, NULL, -1);

        if (!noprompt &&
            EVP_read_pw_string(pass, sizeof pass, "Enter Export Password:"******"Can't read Password\n");
            goto export_end;
        }
        if (!twopass)
            BUF_strlcpy(macpass, pass, sizeof macpass);

        p12 = PKCS12_create(cpass, name, key, ucert, certs,
                            key_pbe, cert_pbe, iter, -1, keytype);

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

        if (macalg) {
            if (!opt_md(macalg, &macmd))
                goto opthelp;
        }

        if (maciter != -1)
            PKCS12_set_mac(p12, mpass, -1, NULL, 0, maciter, macmd);

        i2d_PKCS12_bio(out, p12);

        ret = 0;

 export_end:

        EVP_PKEY_free(key);
        if (certs)
            sk_X509_pop_free(certs, X509_free);
        if (ucert)
            X509_free(ucert);

        goto end;

    }

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

    if (!noprompt
        && EVP_read_pw_string(pass, sizeof pass, "Enter Import Password:"******"Can't read Password\n");
        goto end;
    }

    if (!twopass)
        BUF_strlcpy(macpass, pass, sizeof macpass);

    if ((options & INFO) && p12->mac)
        BIO_printf(bio_err, "MAC Iteration %ld\n",
                   p12->mac->iter ? ASN1_INTEGER_get(p12->mac->iter) : 1);
    if (macver) {
        /* If we enter empty password try no password first */
        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)) {
            BIO_printf(bio_err, "Mac verify error: invalid password?\n");
            ERR_print_errors(bio_err);
            goto end;
        }
    }

    if (!dump_certs_keys_p12(out, p12, cpass, -1, options, passout, enc)) {
        BIO_printf(bio_err, "Error outputting keys and certificates\n");
        ERR_print_errors(bio_err);
        goto end;
    }
    ret = 0;
 end:
    PKCS12_free(p12);
    if (export_cert || inrand)
        app_RAND_write_file(NULL);
    BIO_free(in);
    BIO_free_all(out);
    if (canames)
        sk_OPENSSL_STRING_free(canames);
    if (passin)
        OPENSSL_free(passin);
    if (passout)
        OPENSSL_free(passout);
    return (ret);
}
Beispiel #15
0
// =============================================================
LONGBOW_STOP_DEPRECATED_WARNINGS
// =============================================================

bool
parcPkcs12KeyStore_CreateFile(
    const char *filename,
    const char *password,
    const char *subjectName,
    unsigned keyLength,
    unsigned validityDays)
{
    parcSecurity_AssertIsInitialized();

    bool result = false;

    PARCCertificateFactory *factory = parcCertificateFactory_Create(PARCCertificateType_X509, PARCContainerEncoding_DER);

    PARCBuffer *privateKeyBuffer;
    PARCCertificate *certificate = parcCertificateFactory_CreateSelfSignedCertificate(factory, &privateKeyBuffer, (char *) subjectName, keyLength, validityDays);

    parcCertificateFactory_Release(&factory);

    if (certificate != NULL) {
        // construct the full PKCS12 keystore to hold the certificate and private key

        // Extract the private key
        EVP_PKEY *privateKey = NULL;
        uint8_t *privateKeyBytes = parcBuffer_Overlay(privateKeyBuffer, parcBuffer_Limit(privateKeyBuffer));
        d2i_PrivateKey(EVP_PKEY_RSA, &privateKey, (const unsigned char **) &privateKeyBytes, parcBuffer_Limit(privateKeyBuffer));
        parcBuffer_Release(&privateKeyBuffer);

        // Extract the certificate
        PARCBuffer *certBuffer = parcCertificate_GetDEREncodedCertificate(certificate);
        uint8_t *certBytes = parcBuffer_Overlay(certBuffer, parcBuffer_Limit(certBuffer));
        X509 *cert = NULL;
        d2i_X509(&cert, (const unsigned char **) &certBytes, parcBuffer_Limit(certBuffer));

        parcCertificate_Release(&certificate);

        PKCS12 *pkcs12 = PKCS12_create((char *) password,
                                       "ccnxuser",
                                       privateKey,
                                       cert,
                                       NULL,
                                       0,
                                       0,
                                       0 /*default iter*/,
                                       PKCS12_DEFAULT_ITER /*mac_iter*/,
                                       0);

        if (pkcs12 != NULL) {
            int fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0600);
            if (fd != -1) {
                FILE *fp = fdopen(fd, "wb");
                if (fp != NULL) {
                    i2d_PKCS12_fp(fp, pkcs12);
                    fclose(fp);
                    result = true;
                } else {
                    trapUnrecoverableState("Cannot fdopen(3) the file descriptor %d", fd);
                }
                close(fd);
            } else {
                trapUnrecoverableState("Cannot open(2) the file '%s': %s", filename, strerror(errno));
            }
            PKCS12_free(pkcs12);
            X509_free(cert);
            EVP_PKEY_free(privateKey);
        } else {
            unsigned long errcode;
            while ((errcode = ERR_get_error()) != 0) {
                fprintf(stderr, "openssl error: %s\n", ERR_error_string(errcode, NULL));
            }
            trapUnrecoverableState("PKCS12_create returned a NULL value.");
        }
    }

    return result;
}