/* 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 *) }
PKCS12 * PKCS12_init(int mode) { PKCS12 *pkcs12; if (!(pkcs12 = PKCS12_new())) { PKCS12err(PKCS12_F_PKCS12_INIT, ERR_R_MALLOC_FAILURE); return NULL; } ASN1_INTEGER_set(pkcs12->version, 3); pkcs12->authsafes->type = OBJ_nid2obj(mode); switch (mode) { case NID_pkcs7_data: if (!(pkcs12->authsafes->d.data = ASN1_OCTET_STRING_new())) { PKCS12err(PKCS12_F_PKCS12_INIT, ERR_R_MALLOC_FAILURE); goto err; } break; default: PKCS12err(PKCS12_F_PKCS12_INIT, PKCS12_R_UNSUPPORTED_PKCS12_MODE); goto err; } return pkcs12; err: if (pkcs12 != NULL) PKCS12_free(pkcs12); return NULL; }
/* * Private */ static VALUE ossl_pkcs12_s_allocate(VALUE klass) { PKCS12 *p12; VALUE obj; if(!(p12 = PKCS12_new())) ossl_raise(ePKCS12Error, NULL); WrapPKCS12(klass, obj, p12); return obj; }
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); }