int PEM_write_bio_DSAPrivateKey(BIO *bp, DSA *x, const EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *cb, void *u) { EVP_PKEY *k; int ret; k = EVP_PKEY_new(); if (!k) return 0; EVP_PKEY_set1_DSA(k, x); ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u); EVP_PKEY_free(k); return ret; }
int PEM_write_PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *cb, void *u) { BIO *b; int ret; if ((b = BIO_new_fp(fp, BIO_NOCLOSE)) == NULL) { PEMerr(PEM_F_PEM_WRITE_PRIVATEKEY, ERR_R_BUF_LIB); return 0; } ret = PEM_write_bio_PrivateKey(b, x, enc, kstr, klen, cb, u); BIO_free(b); return ret; }
int pki_write_privatekey(EVP_PKEY *privatekey, const char *filename) { int ret = 0; BIO *bio_file = NULL; bio_file = BIO_new_file(filename, "w"); if (bio_file == NULL) { ret = -1; goto out; } ret = PEM_write_bio_PrivateKey(bio_file, privatekey, NULL, NULL, 0, 0, NULL); if (ret != 1) { ret = -1; goto out; } BIO_free(bio_file); out: return ret; }
TEST(SignTest, TestLoadValidPemKeysWithInvalidPassphrase) { ScopedEVP_PKEY private_key(nullptr, EVP_PKEY_free); ScopedEVP_PKEY public_key(nullptr, EVP_PKEY_free); ScopedBIO bio(BIO_new(BIO_s_mem()), BIO_free); ASSERT_TRUE(!!bio); // Generate keys ASSERT_TRUE(generate_keys(private_key, public_key)); // Write key ASSERT_TRUE(PEM_write_bio_PrivateKey(bio.get(), private_key.get(), EVP_des_ede3_cbc(), nullptr, 0, nullptr, const_cast<char *>("testing"))); // Read back the key using invalid password ScopedEVP_PKEY private_key_read(mb::sign::load_private_key( bio.get(), mb::sign::KEY_FORMAT_PEM, "gnitset"), EVP_PKEY_free); ASSERT_FALSE(private_key_read); }
PyObject * get_key_pem_private(const struct ndn_pkey *private_key_ndn, char *password) { unsigned long err; BIO *bio; BUF_MEM *bufmem; int r; PyObject *py_res; bio = BIO_new(BIO_s_mem()); JUMP_IF_NULL(bio, openssl_error); if (password) { r = PEM_write_bio_PKCS8PrivateKey (bio, (EVP_PKEY *) private_key_ndn, EVP_aes_256_cbc (), NULL, 0, NULL, password); } else { r = PEM_write_bio_PrivateKey(bio, (EVP_PKEY *) private_key_ndn, NULL, NULL, 0, NULL, NULL); } if (!r) goto openssl_error; BIO_get_mem_ptr(bio, &bufmem); py_res = PyBytes_FromStringAndSize(bufmem->data, bufmem->length); r = BIO_free(bio); if (!r) goto openssl_error; return py_res; openssl_error: err = ERR_get_error(); PyErr_Format(g_PyExc_NDNKeyError, "Unable to obtain PEM: %s", ERR_reason_error_string(err)); BIO_free(bio); return NULL; }
int MAIN(int argc, char **argv) { ENGINE *e = NULL; char **args, *infile = NULL, *outfile = NULL; char *passargin = NULL, *passargout = NULL; BIO *in = NULL, *out = NULL; int topk8 = 0; int pbe_nid = -1; const EVP_CIPHER *cipher = NULL; int iter = PKCS12_DEFAULT_ITER; int informat, outformat; int p8_broken = PKCS8_OK; int nocrypt = 0; X509_SIG *p8 = NULL; PKCS8_PRIV_KEY_INFO *p8inf = NULL; EVP_PKEY *pkey=NULL; char pass[50], *passin = NULL, *passout = NULL, *p8pass = NULL; int badarg = 0; int ret = 1; #ifndef OPENSSL_NO_ENGINE char *engine=NULL; #endif if (bio_err == NULL) bio_err = BIO_new_fp (stderr, BIO_NOCLOSE); if (!load_config(bio_err, NULL)) goto end; informat=FORMAT_PEM; outformat=FORMAT_PEM; ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); args = argv + 1; while (!badarg && *args && *args[0] == '-') { if (!strcmp(*args,"-v2")) { if (args[1]) { args++; cipher=EVP_get_cipherbyname(*args); if (!cipher) { BIO_printf(bio_err, "Unknown cipher %s\n", *args); badarg = 1; } } else badarg = 1; } else if (!strcmp(*args,"-v1")) { if (args[1]) { args++; pbe_nid=OBJ_txt2nid(*args); if (pbe_nid == NID_undef) { BIO_printf(bio_err, "Unknown PBE algorithm %s\n", *args); badarg = 1; } } else badarg = 1; } else if (!strcmp(*args,"-v2prf")) { if (args[1]) { args++; pbe_nid=OBJ_txt2nid(*args); if (!EVP_PBE_find(EVP_PBE_TYPE_PRF, pbe_nid, NULL, NULL, 0)) { BIO_printf(bio_err, "Unknown PRF algorithm %s\n", *args); badarg = 1; } } else badarg = 1; } else if (!strcmp(*args,"-inform")) { if (args[1]) { args++; informat=str2fmt(*args); } else badarg = 1; } else if (!strcmp(*args,"-outform")) { if (args[1]) { args++; outformat=str2fmt(*args); } else badarg = 1; } else if (!strcmp (*args, "-topk8")) topk8 = 1; else if (!strcmp (*args, "-noiter")) iter = 1; else if (!strcmp (*args, "-iter")) { if (!args[1]) goto bad; iter = atoi(*(++args)); if (iter <= 0) goto bad; } else if (!strcmp (*args, "-nocrypt")) nocrypt = 1; else if (!strcmp (*args, "-nooct")) p8_broken = PKCS8_NO_OCTET; else if (!strcmp (*args, "-nsdb")) p8_broken = PKCS8_NS_DB; else if (!strcmp (*args, "-embed")) p8_broken = PKCS8_EMBEDDED_PARAM; else if (!strcmp(*args,"-passin")) { if (!args[1]) goto bad; passargin= *(++args); } else if (!strcmp(*args,"-passout")) { if (!args[1]) goto bad; passargout= *(++args); } #ifndef OPENSSL_NO_ENGINE else if (strcmp(*args,"-engine") == 0) { if (!args[1]) goto bad; engine= *(++args); } #endif 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 badarg = 1; args++; } if (badarg) { bad: BIO_printf(bio_err, "Usage pkcs8 [options]\n"); BIO_printf(bio_err, "where options are\n"); BIO_printf(bio_err, "-in file input file\n"); BIO_printf(bio_err, "-inform X input format (DER or PEM)\n"); BIO_printf(bio_err, "-passin arg input file pass phrase source\n"); BIO_printf(bio_err, "-outform X output format (DER or PEM)\n"); BIO_printf(bio_err, "-out file output file\n"); BIO_printf(bio_err, "-passout arg output file pass phrase source\n"); BIO_printf(bio_err, "-topk8 output PKCS8 file\n"); BIO_printf(bio_err, "-nooct use (nonstandard) no octet format\n"); BIO_printf(bio_err, "-embed use (nonstandard) embedded DSA parameters format\n"); BIO_printf(bio_err, "-nsdb use (nonstandard) DSA Netscape DB format\n"); BIO_printf(bio_err, "-iter count use count as iteration count\n"); BIO_printf(bio_err, "-noiter use 1 as iteration count\n"); BIO_printf(bio_err, "-nocrypt use or expect unencrypted private key\n"); BIO_printf(bio_err, "-v2 alg use PKCS#5 v2.0 and cipher \"alg\"\n"); BIO_printf(bio_err, "-v1 obj use PKCS#5 v1.5 and cipher \"alg\"\n"); #ifndef OPENSSL_NO_ENGINE BIO_printf(bio_err," -engine e use engine e, possibly a hardware device.\n"); #endif goto end; } #ifndef OPENSSL_NO_ENGINE e = setup_engine(bio_err, engine, 0); #endif if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) { BIO_printf(bio_err, "Error getting passwords\n"); goto end; } if ((pbe_nid == -1) && !cipher) pbe_nid = NID_pbeWithMD5AndDES_CBC; if (infile) { if (!(in = BIO_new_file(infile, "rb"))) { BIO_printf(bio_err, "Can't open input file %s\n", infile); goto end; } } else in = BIO_new_fp (stdin, BIO_NOCLOSE); if (outfile) { if (!(out = BIO_new_file (outfile, "wb"))) { BIO_printf(bio_err, "Can't open output file %s\n", outfile); goto end; } } else { out = BIO_new_fp (stdout, BIO_NOCLOSE); #ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); out = BIO_push(tmpbio, out); } #endif } if (topk8) { pkey = load_key(bio_err, infile, informat, 1, passin, e, "key"); if (!pkey) goto end; if (!(p8inf = EVP_PKEY2PKCS8_broken(pkey, p8_broken))) { BIO_printf(bio_err, "Error converting key\n"); ERR_print_errors(bio_err); goto end; } if (nocrypt) { if (outformat == FORMAT_PEM) PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8inf); else if (outformat == FORMAT_ASN1) i2d_PKCS8_PRIV_KEY_INFO_bio(out, p8inf); else { BIO_printf(bio_err, "Bad format specified for key\n"); goto end; } } else { if (passout) p8pass = passout; else { p8pass = pass; if (EVP_read_pw_string(pass, sizeof pass, "Enter Encryption Password:"******"Error encrypting key\n"); ERR_print_errors(bio_err); goto end; } app_RAND_write_file(NULL, bio_err); if (outformat == FORMAT_PEM) PEM_write_bio_PKCS8(out, p8); else if (outformat == FORMAT_ASN1) i2d_PKCS8_bio(out, p8); else { BIO_printf(bio_err, "Bad format specified for key\n"); goto end; } } ret = 0; goto end; } if (nocrypt) { if (informat == FORMAT_PEM) p8inf = PEM_read_bio_PKCS8_PRIV_KEY_INFO(in,NULL,NULL, NULL); else if (informat == FORMAT_ASN1) p8inf = d2i_PKCS8_PRIV_KEY_INFO_bio(in, NULL); else { BIO_printf(bio_err, "Bad format specified for key\n"); goto end; } } else { if (informat == FORMAT_PEM) p8 = PEM_read_bio_PKCS8(in, NULL, NULL, NULL); else if (informat == FORMAT_ASN1) p8 = d2i_PKCS8_bio(in, NULL); else { BIO_printf(bio_err, "Bad format specified for key\n"); goto end; } if (!p8) { BIO_printf (bio_err, "Error reading key\n"); ERR_print_errors(bio_err); goto end; } if (passin) p8pass = passin; else { p8pass = pass; EVP_read_pw_string(pass, sizeof pass, "Enter Password:"******"Error decrypting key\n"); ERR_print_errors(bio_err); goto end; } if (!(pkey = EVP_PKCS82PKEY(p8inf))) { BIO_printf(bio_err, "Error converting key\n"); ERR_print_errors(bio_err); goto end; } if (p8inf->broken) { BIO_printf(bio_err, "Warning: broken key encoding: "); switch (p8inf->broken) { case PKCS8_NO_OCTET: BIO_printf(bio_err, "No Octet String in PrivateKey\n"); break; case PKCS8_EMBEDDED_PARAM: BIO_printf(bio_err, "DSA parameters included in PrivateKey\n"); break; case PKCS8_NS_DB: BIO_printf(bio_err, "DSA public key include in PrivateKey\n"); break; case PKCS8_NEG_PRIVKEY: BIO_printf(bio_err, "DSA private key value is negative\n"); break; default: BIO_printf(bio_err, "Unknown broken type\n"); break; } } if (outformat == FORMAT_PEM) PEM_write_bio_PrivateKey(out, pkey, NULL, NULL, 0, NULL, passout); else if (outformat == FORMAT_ASN1) i2d_PrivateKey_bio(out, pkey); else { BIO_printf(bio_err, "Bad format specified for key\n"); goto end; } ret = 0; end: X509_SIG_free(p8); PKCS8_PRIV_KEY_INFO_free(p8inf); EVP_PKEY_free(pkey); BIO_free_all(out); BIO_free(in); if (passin) OPENSSL_free(passin); if (passout) OPENSSL_free(passout); return ret; }
static LUA_FUNCTION(openssl_pkey_export) { EVP_PKEY * key; int ispriv = 0; int exraw = 0; int expem = 1; size_t passphrase_len = 0; BIO * bio_out = NULL; int ret = 0; const EVP_CIPHER * cipher; const char * passphrase = NULL; key = CHECK_OBJECT(1, EVP_PKEY, "openssl.evp_pkey"); ispriv = openssl_pkey_is_private(key); if (!lua_isnoneornil(L, 2)) expem = lua_toboolean(L, 2); if (expem) { if (!lua_isnoneornil(L, 3)) exraw = lua_toboolean(L, 3); passphrase = luaL_optlstring(L, 4, NULL, &passphrase_len); } else { passphrase = luaL_optlstring(L, 3, NULL, &passphrase_len); } if (passphrase) { cipher = (EVP_CIPHER *) EVP_des_ede3_cbc(); } else { cipher = NULL; } bio_out = BIO_new(BIO_s_mem()); if (expem) { if (exraw==0) { ret = ispriv ? PEM_write_bio_PrivateKey(bio_out, key, cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL) : PEM_write_bio_PUBKEY(bio_out, key); } else { /* export raw key format */ switch (EVP_PKEY_type(key->type)) { case EVP_PKEY_RSA: case EVP_PKEY_RSA2: ret = ispriv ? PEM_write_bio_RSAPrivateKey(bio_out, key->pkey.rsa, cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL) : PEM_write_bio_RSAPublicKey(bio_out, key->pkey.rsa); break; case EVP_PKEY_DSA: case EVP_PKEY_DSA2: case EVP_PKEY_DSA3: case EVP_PKEY_DSA4: { ret = ispriv ? PEM_write_bio_DSAPrivateKey(bio_out, key->pkey.dsa, cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL) : PEM_write_bio_DSA_PUBKEY(bio_out, key->pkey.dsa); } break; case EVP_PKEY_DH: ret = PEM_write_bio_DHparams(bio_out, key->pkey.dh); break; #ifndef OPENSSL_NO_EC case EVP_PKEY_EC: ret = ispriv ? PEM_write_bio_ECPrivateKey(bio_out, key->pkey.ec, cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL) : PEM_write_bio_EC_PUBKEY(bio_out, key->pkey.ec); break; #endif default: ret = 0; break; } } } else { if (ispriv) { if (passphrase == NULL) { ret = i2d_PrivateKey_bio(bio_out, key); } else { ret = i2d_PKCS8PrivateKey_bio(bio_out, key, cipher, (char *)passphrase, passphrase_len, NULL, NULL); } } else { int l; l = i2d_PublicKey(key, NULL); if (l > 0) { unsigned char* p = malloc(l); unsigned char* pp = p; l = i2d_PublicKey(key, &pp); if (l > 0) { BIO_write(bio_out, p, l); ret = 1; } else ret = 0; free(p); } else ret = 0; } } if (ret) { char * bio_mem_ptr; long bio_mem_len; bio_mem_len = BIO_get_mem_data(bio_out, &bio_mem_ptr); lua_pushlstring(L, bio_mem_ptr, bio_mem_len); ret = 1; } if (bio_out) { BIO_free(bio_out); } return ret; }
LWS_VISIBLE LWS_EXTERN int lws_tls_acme_sni_csr_create(struct lws_context *context, const char *elements[], uint8_t *csr, size_t csr_len, char **privkey_pem, size_t *privkey_len) { uint8_t *csr_in = csr; RSA *rsakey; X509_REQ *req; X509_NAME *subj; EVP_PKEY *pkey; char *p, *end; BIO *bio; long bio_len; int n, ret = -1; if (lws_tls_openssl_rsa_new_key(&rsakey, 4096)) return -1; pkey = EVP_PKEY_new(); if (!pkey) goto bail0; if (!EVP_PKEY_set1_RSA(pkey, rsakey)) goto bail1; req = X509_REQ_new(); if (!req) goto bail1; X509_REQ_set_pubkey(req, pkey); subj = X509_NAME_new(); if (!subj) goto bail2; for (n = 0; n < LWS_TLS_REQ_ELEMENT_COUNT; n++) if (lws_tls_openssl_add_nid(subj, nid_list[n], elements[n])) { lwsl_notice("%s: failed to add element %d\n", __func__, n); goto bail3; } if (X509_REQ_set_subject_name(req, subj) != 1) goto bail3; if (!X509_REQ_sign(req, pkey, EVP_sha256())) goto bail3; /* * issue the CSR as PEM to a BIO, and translate to b64urlenc without * headers, trailers, or whitespace */ bio = BIO_new(BIO_s_mem()); if (!bio) goto bail3; if (PEM_write_bio_X509_REQ(bio, req) != 1) { BIO_free(bio); goto bail3; } bio_len = BIO_get_mem_data(bio, &p); end = p + bio_len; /* strip the header line */ while (p < end && *p != '\n') p++; while (p < end && csr_len) { if (*p == '\n') { p++; continue; } if (*p == '-') break; if (*p == '+') *csr++ = '-'; else if (*p == '/') *csr++ = '_'; else *csr++ = *p; p++; csr_len--; } BIO_free(bio); if (!csr_len) { lwsl_notice("%s: need %ld for CSR\n", __func__, bio_len); goto bail3; } /* * Also return the private key as a PEM in memory * (platform may not have a filesystem) */ bio = BIO_new(BIO_s_mem()); if (!bio) goto bail3; if (PEM_write_bio_PrivateKey(bio, pkey, NULL, NULL, 0, 0, NULL) != 1) { BIO_free(bio); goto bail3; } bio_len = BIO_get_mem_data(bio, &p); *privkey_pem = malloc(bio_len); /* malloc so user code can own / free */ *privkey_len = (size_t)bio_len; if (!*privkey_pem) { lwsl_notice("%s: need %ld for private key\n", __func__, bio_len); BIO_free(bio); goto bail3; } memcpy(*privkey_pem, p, (int)(long long)bio_len); BIO_free(bio); ret = lws_ptr_diff(csr, csr_in); bail3: X509_NAME_free(subj); bail2: X509_REQ_free(req); bail1: EVP_PKEY_free(pkey); bail0: RSA_free(rsakey); return ret; }
/** * \fn resultP12ToPem p12ToPem (string, string) * \brief Convert P12 to PEM * \param string p12File Path to P12 file * \param string p12Passwd Password to open P12 file * \return result (bool ReturnCode, Int ErrorCode, String Comment, String PrivateKey, String Certificate) */ resultP12ToPem p12ToPem(string p12File, string p12Passwd) { FILE *fp; PKCS12 *p12 = NULL; EVP_PKEY *pkey = NULL; X509 *cert = NULL; STACK_OF(X509) *ca = NULL; BIO *o = BIO_new(BIO_s_mem()); string privateKey = ""; string certificate = ""; resultP12ToPem ret; ret.ReturnCode = false; ret.ErrorCode = 0; ret.Comment = ""; ret.PrivateKey = ""; ret.Certificate = ""; SSLeay_add_all_algorithms(); ERR_load_crypto_strings(); if(!(fp = fopen(p12File.c_str(), "rb"))) { ret.ErrorCode = 1; ret.Comment = strerror(errno); return ret; } p12 = d2i_PKCS12_fp(fp, &p12); fclose (fp); if (!p12) { ret.ErrorCode = 2; ret.Comment = "Unable to open PKCS#12 file"; return ret; } if (!PKCS12_parse(p12, p12Passwd.c_str(), &pkey, &cert, &ca)) { ret.ErrorCode = 3; ret.Comment = "Unable to parse PKCS#12 file (wrong password ?)"; return ret; } PKCS12_free(p12); if (!(pkey && cert)) { ret.ErrorCode = 4; ret.Comment = "Certificate and/or key file doesn't exists"; } else { PEM_write_bio_PrivateKey(o, pkey, 0, 0, 0, NULL, 0); privateKey = x509ToString(o); PEM_write_bio_X509(o, cert); certificate = x509ToString(o); BIO_free(o); ret.ReturnCode = true; ret.ErrorCode = 0; ret.Comment = "All is fine"; ret.PrivateKey = privateKey; ret.Certificate = certificate; } return ret; }
BSONObj createCertificateRequest(const BSONObj& a, void* data) { #ifndef MONGO_CONFIG_SSL return BSON( "" << BSON("ok" << false << "errmsg" << "Cannot create a certificate signing request without SSL support")); #else if (a.nFields() != 1 || a.firstElement().type() != Object) { return BSON( "" << BSON("ok" << false << "errmsg" << "createCertificateRequest requires a single object argument")); } // args can optionally contain some to be determined fields... BSONObj args = a.firstElement().embeddedObject(); if (!args.hasField("CN")) { return BSON( "" << BSON("ok" << false << "errmsg" << "createCertificateRequest requires a Common Name (\"CN\") field")); } // Generate key pair and certificate signing request RSA* rsa; EVP_PKEY* pkey; X509_REQ* x509req; X509_NAME* name; BIO* out; char client_key[2048]; char client_csr[2048]; pkey = EVP_PKEY_new(); if (!pkey) { return BSON("" << BSON("ok" << false)); // fail("couldn't generate key"); } rsa = RSA_generate_key(2048, RSA_F4, NULL, NULL); if (!EVP_PKEY_assign_RSA(pkey, rsa)) { return BSON("" << BSON("ok" << false)); // fail("couldn't assign the key"); } x509req = X509_REQ_new(); X509_REQ_set_pubkey(x509req, pkey); name = X509_NAME_new(); X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC, (const unsigned char*)"IS", -1, -1, 0); X509_NAME_add_entry_by_txt(name, "O", MBSTRING_ASC, (const unsigned char*)"MongoDB", -1, -1, 0); X509_NAME_add_entry_by_txt( name, "OU", MBSTRING_ASC, (const unsigned char*)"SkunkWorks client", -1, -1, 0); X509_NAME_add_entry_by_txt( name, "CN", MBSTRING_ASC, (const unsigned char*)args.getStringField("CN"), -1, -1, 0); X509_REQ_set_subject_name(x509req, name); X509_REQ_set_version(x509req, 2); if (!X509_REQ_sign(x509req, pkey, EVP_sha1())) { return BSON("" << BSON("ok" << false)); } // out = BIO_new_file("client.key.pem", "wb"); out = BIO_new(BIO_s_mem()); if (!PEM_write_bio_PrivateKey(out, pkey, NULL, NULL, 0, NULL, NULL)) { return BSON("" << BSON("ok" << false)); // fail("can't write private key"); } int i = BIO_read(out, &client_key, sizeof client_key); client_key[i] = '\0'; BIO_free_all(out); out = BIO_new(BIO_s_mem()); if (!PEM_write_bio_X509_REQ_NEW(out, x509req)) { return BSON("" << BSON("ok" << false)); // fail("coudln't write csr"); } i = BIO_read(out, &client_csr, sizeof client_csr); client_csr[i] = '\0'; BIO_free_all(out); EVP_PKEY_free(pkey); X509_REQ_free(x509req); return BSON("" << BSON("ok" << true << "certificateRequest" << client_csr << "privateKey" << client_key)); #endif }
//static bool OTAsymmetricKey_OpenSSL::OTAsymmetricKey_OpenSSLPrivdp::ArmorPrivateKey(EVP_PKEY & theKey, OTASCIIArmor & ascKey, Timer & theTimer, OTPasswordData * pPWData/*=NULL*/, OTPassword * pImportPassword/*=NULL*/) { bool bReturnVal = false; ascKey.Release(); // ---------------------------------------- // Create a new memory buffer on the OpenSSL side OpenSSL_BIO bmem = BIO_new(BIO_s_mem()); OT_ASSERT(NULL != bmem); int64_t lSize = 0; // ---------------------------------------- // write a private key to that buffer, from theKey // OTPasswordData thePWData("OTAsymmetricKey_OpenSSL::ArmorPrivateKey is calling PEM_write_bio_PrivateKey..."); if (NULL == pPWData) pPWData = &thePWData; int32_t nWriteBio = 0; if (NULL == pImportPassword) nWriteBio = PEM_write_bio_PrivateKey(bmem, &theKey, EVP_des_ede3_cbc(), // todo should this algorithm be hardcoded? NULL, 0, OTAsymmetricKey::GetPasswordCallback(), pPWData); else nWriteBio = PEM_write_bio_PrivateKey(bmem, &theKey, EVP_des_ede3_cbc(), // todo should this algorithm be hardcoded? NULL, 0, 0, const_cast<void*>(reinterpret_cast<const void*>(pImportPassword->getPassword()))); if (0 == nWriteBio) { OTLog::vError("%s: Failed writing EVP_PKEY to memory buffer.\n", __FUNCTION__); } else { // TODO (remove theTimer entirely. OTCachedKey replaces already.) // I set this timer because the above required a password. But now that master key is working, // the above would flow through even WITHOUT the user typing his passphrase (since master key still // not timed out.) Resulting in THIS timer being reset! Todo: I already shortened this timer to 30 // seconds, but need to phase it down to 0 and then remove it entirely! Master key takes over now! // theTimer.start(); // Note: this isn't the ultimate timer solution. See notes in ReleaseKeyLowLevel. // -------------------- OTLog::vOutput(5, "%s: Success writing EVP_PKEY to memory buffer.\n", __FUNCTION__); OTPayload theData; char * pChar = NULL; // After the below call, pChar will point to the memory buffer where the private key supposedly is, // and lSize will contain the size of that memory. // lSize = BIO_get_mem_data(bmem, &pChar); uint32_t nSize = static_cast<uint32_t>(lSize); if (nSize > 0) { // Set the buffer size in our own memory. theData.SetPayloadSize(nSize); // void * pv = OTPassword::safe_memcpy((static_cast<char*>(const_cast<void*>(theData.GetPayloadPointer()))), // destination theData.GetSize(), // size of destination buffer. pChar, // source nSize); // length of source. // bool bZeroSource=false); // if true, sets the source buffer to zero after copying is done. // ------------------------------------------------ // This base64 encodes the private key data, which // is already encrypted to its passphase as well. // ascKey.SetData(theData); OTLog::vOutput(5, "%s: Success copying private key into memory.\n", __FUNCTION__); bReturnVal = true; } else { OTLog::vError("%s: Failed copying private key into memory.\n", __FUNCTION__); } } return bReturnVal; }
// NOTE: OpenSSL will store the EVP_PKEY inside the X509, and when I get it, // I'm not supposed to destroy the x509 until I destroy the EVP_PKEY FIRST! // (AND it reference-counts.) // Since I want ability to destroy the two, independent of each other, I made // static functions here for copying public and private keys, so I am ALWAYS // working with MY OWN copy of any given key, and not OpenSSL's reference-counted // one. // // Furthermore, BIO_mem_buf doesn't allocate its own memory, but uses the memory // you pass to it. You CANNOT free that memory until you destroy the BIO. // // That's why you see me copying one bio into a payload, before copying it into // the next bio. Todo security: copy it into an OTPassword here, instead of an // OTPayload, which is safer, and more appropriate for a private key. Make sure // OTPassword can accommodate a bit larger size than what it does now. // //static // CALLER must EVP_pkey_free! EVP_PKEY * OTAsymmetricKey_OpenSSL::OTAsymmetricKey_OpenSSLPrivdp::CopyPrivateKey(EVP_PKEY & theKey, OTPasswordData * pPWData/*=NULL*/, OTPassword * pImportPassword/*=NULL*/) { const EVP_CIPHER * pCipher = EVP_des_ede3_cbc(); // todo should this algorithm be hardcoded? // ---------------------------------------- // Create a new memory buffer on the OpenSSL side OpenSSL_BIO bmem = BIO_new(BIO_s_mem()); OT_ASSERT(NULL != bmem); EVP_PKEY * pReturnKey = NULL; // ---------------------------------------- // write a private key to that buffer, from theKey // OTPasswordData thePWDataWrite("OTAsymmetricKey_OpenSSL::CopyPrivateKey is calling PEM_write_bio_PrivateKey..."); // todo optimization: might just remove the password callback here, and just write the private key in the clear, // and then load it up again, saving the encrypt/decrypt step that otherwise occurs, and then as long as we OpenSSL_cleanse // the BIO, then it SHOULD stil be safe, right? // int32_t nWriteBio = false; if (NULL == pImportPassword) nWriteBio = PEM_write_bio_PrivateKey(bmem, &theKey, pCipher, NULL, 0, OTAsymmetricKey::GetPasswordCallback(), NULL == pPWData ? &thePWDataWrite : pPWData); else nWriteBio = PEM_write_bio_PrivateKey(bmem, &theKey, pCipher, NULL, 0, 0, const_cast<void*>(reinterpret_cast<const void*>(pImportPassword->getPassword()))); // ------------------------------------------------------------------------ if (0 == nWriteBio) { OTLog::vError("%s: Failed writing EVP_PKEY to memory buffer.\n", __FUNCTION__); } else { OTLog::vOutput(5, "%s: Success writing EVP_PKEY to memory buffer.\n", __FUNCTION__); char * pChar = NULL; // After the below call, pChar will point to the memory buffer where the private key supposedly is, // and lSize will contain the size of that memory. // const int64_t lSize = BIO_get_mem_data(bmem, &pChar); const uint32_t nSize = static_cast<uint32_t>(lSize); if (nSize > 0) { OTPayload theData; // Set the buffer size in our own memory. theData.SetPayloadSize(nSize); void * pv = OTPassword::safe_memcpy((static_cast<char*>(const_cast<void*>(theData.GetPayloadPointer()))), // destination theData.GetSize(), // size of destination buffer. pChar, // source nSize); // length of source. // bool bZeroSource=false); // if true, sets the source buffer to zero after copying is done. if (NULL != pv) { // ----------------------------------------------- // Next, copy theData's contents into a new BIO_mem_buf, // so OpenSSL can load the key out of it. // OpenSSL_BIO keyBio = BIO_new_mem_buf(static_cast<char*>(const_cast<void*>(theData.GetPayloadPointer())), theData.GetSize()); OT_ASSERT_MSG(NULL != keyBio, "OTAsymmetricKey_OpenSSL::CopyPrivateKey: Assert: NULL != keyBio \n"); // ------------------------------------------- // Next we load up the key from the BIO string into an instantiated key object. // OTPasswordData thePWData("OTAsymmetricKey_OpenSSL::CopyPrivateKey is calling PEM_read_bio_PUBKEY..."); if (NULL == pImportPassword) pReturnKey = PEM_read_bio_PrivateKey( keyBio, NULL, OTAsymmetricKey::GetPasswordCallback(), NULL == pPWData ? &thePWData : pPWData); else pReturnKey = PEM_read_bio_PrivateKey( keyBio, NULL, 0, const_cast<void*>(reinterpret_cast<const void*>(pImportPassword->getPassword()))); // ------------------------------------------- } else OTLog::vError("%s: Error: Failed copying memory from BIO into OTPayload.\n"); // ------------------------------------------- } else { OTLog::vError("%s: Failed copying private key into memory.\n", __FUNCTION__); } } return pReturnKey; }
char * ssl_load_key(const char *name, off_t *len, char *pass, mode_t perm, const char *pkiname) { FILE *fp = NULL; EVP_PKEY *key = NULL; BIO *bio = NULL; long size; char *data, *buf = NULL; struct stat st; char mode[12]; char prompt[2048]; /* Initialize SSL library once */ ssl_init(); /* * Read (possibly) encrypted key from file */ if ((fp = fopen(name, "r")) == NULL) return (NULL); if (fstat(fileno(fp), &st) != 0) goto fail; if (st.st_uid != 0) { log_warnx("warn: %s: not owned by uid 0", name); errno = EACCES; goto fail; } if (st.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO) & ~perm) { strmode(perm, mode); log_warnx("warn: %s: insecure permissions: must be at most %s", name, &mode[1]); errno = EACCES; goto fail; } (void)snprintf(prompt, sizeof prompt, "passphrase for %s: ", pkiname); key = PEM_read_PrivateKey(fp, NULL, ssl_password_cb, prompt); fclose(fp); fp = NULL; if (key == NULL) goto fail; /* * Write unencrypted key to memory buffer */ if ((bio = BIO_new(BIO_s_mem())) == NULL) goto fail; if (!PEM_write_bio_PrivateKey(bio, key, NULL, NULL, 0, NULL, NULL)) goto fail; if ((size = BIO_get_mem_data(bio, &data)) <= 0) goto fail; if ((buf = calloc(1, size + 1)) == NULL) goto fail; memcpy(buf, data, size); BIO_free_all(bio); EVP_PKEY_free(key); *len = (off_t)size + 1; return (buf); fail: ssl_error("ssl_load_key"); free(buf); if (bio != NULL) BIO_free_all(bio); if (key != NULL) EVP_PKEY_free(key); if (fp) fclose(fp); return (NULL); }
int pkcs8_main(int argc, char **argv) { BIO *in = NULL, *out = NULL; ENGINE *e = NULL; EVP_PKEY *pkey = NULL; PKCS8_PRIV_KEY_INFO *p8inf = NULL; X509_SIG *p8 = NULL; const EVP_CIPHER *cipher = NULL; char *infile = NULL, *outfile = NULL; char *passinarg = NULL, *passoutarg = NULL, *prog; char pass[50], *passin = NULL, *passout = NULL, *p8pass = NULL; OPTION_CHOICE o; int nocrypt = 0, ret = 1, iter = PKCS12_DEFAULT_ITER, p8_broken = PKCS8_OK; int informat = FORMAT_PEM, outformat = FORMAT_PEM, topk8 = 0, pbe_nid = -1; prog = opt_init(argc, argv, pkcs8_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(pkcs8_options); ret = 0; goto end; case OPT_INFORM: if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat)) goto opthelp; break; case OPT_IN: infile = opt_arg(); break; case OPT_OUTFORM: if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat)) goto opthelp; break; case OPT_OUT: outfile = opt_arg(); break; case OPT_TOPK8: topk8 = 1; break; case OPT_NOITER: iter = 1; break; case OPT_NOCRYPT: nocrypt = 1; break; case OPT_NOOCT: p8_broken = PKCS8_NO_OCTET; break; case OPT_NSDB: p8_broken = PKCS8_NS_DB; break; case OPT_EMBED: p8_broken = PKCS8_EMBEDDED_PARAM; break; case OPT_V2: if (!opt_cipher(opt_arg(), &cipher)) goto opthelp; break; case OPT_V1: pbe_nid = OBJ_txt2nid(opt_arg()); if (pbe_nid == NID_undef) { BIO_printf(bio_err, "%s: Unknown PBE algorithm %s\n", prog, opt_arg()); goto opthelp; } break; case OPT_V2PRF: pbe_nid = OBJ_txt2nid(opt_arg()); if (!EVP_PBE_find(EVP_PBE_TYPE_PRF, pbe_nid, NULL, NULL, 0)) { BIO_printf(bio_err, "%s: Unknown PRF algorithm %s\n", prog, opt_arg()); goto opthelp; } break; case OPT_ITER: if (!opt_int(opt_arg(), &iter)) goto opthelp; break; case OPT_PASSIN: passinarg = opt_arg(); break; case OPT_PASSOUT: passoutarg = opt_arg(); break; case OPT_ENGINE: e = setup_engine(opt_arg(), 0); break; } } argc = opt_num_rest(); argv = opt_rest(); if (!app_passwd(passinarg, passoutarg, &passin, &passout)) { BIO_printf(bio_err, "Error getting passwords\n"); goto end; } if ((pbe_nid == -1) && !cipher) pbe_nid = NID_pbeWithMD5AndDES_CBC; in = bio_open_default(infile, "rb"); if (in == NULL) goto end; out = bio_open_default(outfile, "wb"); if (out == NULL) goto end; if (topk8) { pkey = load_key(infile, informat, 1, passin, e, "key"); if (!pkey) goto end; if (!(p8inf = EVP_PKEY2PKCS8_broken(pkey, p8_broken))) { BIO_printf(bio_err, "Error converting key\n"); ERR_print_errors(bio_err); goto end; } if (nocrypt) { if (outformat == FORMAT_PEM) PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8inf); else if (outformat == FORMAT_ASN1) i2d_PKCS8_PRIV_KEY_INFO_bio(out, p8inf); else { BIO_printf(bio_err, "Bad format specified for key\n"); goto end; } } else { if (passout) p8pass = passout; else { p8pass = pass; if (EVP_read_pw_string (pass, sizeof pass, "Enter Encryption Password:"******"Error encrypting key\n"); ERR_print_errors(bio_err); goto end; } app_RAND_write_file(NULL); if (outformat == FORMAT_PEM) PEM_write_bio_PKCS8(out, p8); else if (outformat == FORMAT_ASN1) i2d_PKCS8_bio(out, p8); else { BIO_printf(bio_err, "Bad format specified for key\n"); goto end; } } ret = 0; goto end; } if (nocrypt) { if (informat == FORMAT_PEM) p8inf = PEM_read_bio_PKCS8_PRIV_KEY_INFO(in, NULL, NULL, NULL); else if (informat == FORMAT_ASN1) p8inf = d2i_PKCS8_PRIV_KEY_INFO_bio(in, NULL); else { BIO_printf(bio_err, "Bad format specified for key\n"); goto end; } } else { if (informat == FORMAT_PEM) p8 = PEM_read_bio_PKCS8(in, NULL, NULL, NULL); else if (informat == FORMAT_ASN1) p8 = d2i_PKCS8_bio(in, NULL); else { BIO_printf(bio_err, "Bad format specified for key\n"); goto end; } if (!p8) { BIO_printf(bio_err, "Error reading key\n"); ERR_print_errors(bio_err); goto end; } if (passin) p8pass = passin; else { p8pass = pass; EVP_read_pw_string(pass, sizeof pass, "Enter Password:"******"Error decrypting key\n"); ERR_print_errors(bio_err); goto end; } if (!(pkey = EVP_PKCS82PKEY(p8inf))) { BIO_printf(bio_err, "Error converting key\n"); ERR_print_errors(bio_err); goto end; } if (p8inf->broken) { BIO_printf(bio_err, "Warning: broken key encoding: "); switch (p8inf->broken) { case PKCS8_NO_OCTET: BIO_printf(bio_err, "No Octet String in PrivateKey\n"); break; case PKCS8_EMBEDDED_PARAM: BIO_printf(bio_err, "DSA parameters included in PrivateKey\n"); break; case PKCS8_NS_DB: BIO_printf(bio_err, "DSA public key include in PrivateKey\n"); break; case PKCS8_NEG_PRIVKEY: BIO_printf(bio_err, "DSA private key value is negative\n"); break; default: BIO_printf(bio_err, "Unknown broken type\n"); break; } } if (outformat == FORMAT_PEM) PEM_write_bio_PrivateKey(out, pkey, NULL, NULL, 0, NULL, passout); else if (outformat == FORMAT_ASN1) i2d_PrivateKey_bio(out, pkey); else { BIO_printf(bio_err, "Bad format specified for key\n"); goto end; } ret = 0; end: X509_SIG_free(p8); PKCS8_PRIV_KEY_INFO_free(p8inf); EVP_PKEY_free(pkey); BIO_free_all(out); BIO_free(in); OPENSSL_free(passin); OPENSSL_free(passout); return ret; }
ConnectionInitiator::ConnectionInitiator(QObject *parent) : QObject(parent) { this->qSql = DatabaseHandler::getInstance(); // generate self-signed certificate // this bit is inspired by http://stackoverflow.com/questions/256405/programmatically-create-x509-certificate-using-openssl EVP_PKEY* pkey; pkey = EVP_PKEY_new(); RSA* rsa = RSA_generate_key(2048, RSA_F4, NULL, NULL); if (!EVP_PKEY_assign_RSA(pkey, rsa)) { qWarning() << "Unable to generate 2048-bit RSA key"; UnixSignalHandler::termSignalHandler(0); } X509* x509 = X509_new(); ASN1_INTEGER_set(X509_get_serialNumber(x509), 1); X509_gmtime_adj(X509_get_notBefore(x509), -2000); X509_gmtime_adj(X509_get_notAfter(x509), 31536000L); X509_set_pubkey(x509, pkey); X509_NAME * name = X509_get_subject_name(x509); X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC, (unsigned char *)"BE", -1, -1, 0); X509_NAME_add_entry_by_txt(name, "O", MBSTRING_ASC, (unsigned char *)"FriendsVPN", -1, -1, 0); X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (unsigned char *)"facebookApp", -1, -1, 0); X509_set_issuer_name(x509, name); if (!X509_sign(x509, pkey, EVP_sha1())) { qWarning() << "Error signing certificate"; UnixSignalHandler::termSignalHandler(0); } // get the PEM string for cert and key // cert BIO* bio = BIO_new(BIO_s_mem()); PEM_write_bio_X509(bio, x509); BUF_MEM *bptr; BIO_get_mem_ptr(bio, &bptr); int length = bptr->length; char certBuf[length + 1]; BIO_read(bio, certBuf, length); certBuf[length] = '\0'; BIO_free(bio); // key bio = BIO_new(BIO_s_mem()); PEM_write_bio_PrivateKey(bio, pkey, NULL, NULL, 0, NULL, NULL); BIO_get_mem_ptr(bio, &bptr); length = bptr->length; char keyBuf[length + 1]; BIO_read(bio, keyBuf, length); keyBuf[length] = '\0'; BIO_free(bio); qDebug() << "Printing local key and certificate"; qDebug() << keyBuf; qDebug() << certBuf; key = QSslKey(keyBuf, QSsl::Rsa, QSsl::Pem); cert = QSslCertificate(certBuf, QSsl::Pem); qSql->pushCert(cert); }
int MAIN(int argc, char **argv) { ENGINE *e = NULL; char **args, *infile = NULL, *outfile = NULL; char *passargin = NULL, *passargout = NULL; BIO *in = NULL, *out = NULL; const EVP_CIPHER *cipher = NULL; int informat, outformat; int pubin = 0, pubout = 0, pubtext = 0, text = 0, noout = 0; EVP_PKEY *pkey = NULL; char *passin = NULL, *passout = NULL; int badarg = 0; #ifndef OPENSSL_NO_ENGINE char *engine = NULL; #endif int ret = 1; if (bio_err == NULL) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); if (!load_config(bio_err, NULL)) goto end; informat = FORMAT_PEM; outformat = FORMAT_PEM; ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); args = argv + 1; while (!badarg && *args && *args[0] == '-') { if (!strcmp(*args, "-inform")) { if (args[1]) { args++; informat = str2fmt(*args); } else badarg = 1; } else if (!strcmp(*args, "-outform")) { if (args[1]) { args++; outformat = str2fmt(*args); } else badarg = 1; } else if (!strcmp(*args, "-passin")) { if (!args[1]) goto bad; passargin = *(++args); } else if (!strcmp(*args, "-passout")) { if (!args[1]) goto bad; passargout = *(++args); } #ifndef OPENSSL_NO_ENGINE else if (strcmp(*args, "-engine") == 0) { if (!args[1]) goto bad; engine = *(++args); } #endif 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, "-pubin") == 0) { pubin = 1; pubout = 1; pubtext = 1; } else if (strcmp(*args, "-pubout") == 0) pubout = 1; else if (strcmp(*args, "-text_pub") == 0) { pubtext = 1; text = 1; } else if (strcmp(*args, "-text") == 0) text = 1; else if (strcmp(*args, "-noout") == 0) noout = 1; else { cipher = EVP_get_cipherbyname(*args + 1); if (!cipher) { BIO_printf(bio_err, "Unknown cipher %s\n", *args + 1); badarg = 1; } } args++; } if (badarg) { bad: BIO_printf(bio_err, "Usage pkey [options]\n"); BIO_printf(bio_err, "where options are\n"); BIO_printf(bio_err, "-in file input file\n"); BIO_printf(bio_err, "-inform X input format (DER or PEM)\n"); BIO_printf(bio_err, "-passin arg input file pass phrase source\n"); BIO_printf(bio_err, "-outform X output format (DER or PEM)\n"); BIO_printf(bio_err, "-out file output file\n"); BIO_printf(bio_err, "-passout arg 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 return 1; } #ifndef OPENSSL_NO_ENGINE e = setup_engine(bio_err, engine, 0); #endif if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) { BIO_printf(bio_err, "Error getting passwords\n"); goto end; } if (outfile) { if (!(out = BIO_new_file(outfile, "wb"))) { BIO_printf(bio_err, "Can't open output file %s\n", outfile); goto end; } } else { out = BIO_new_fp(stdout, BIO_NOCLOSE); #ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); out = BIO_push(tmpbio, out); } #endif } if (pubin) pkey = load_pubkey(bio_err, infile, informat, 1, passin, e, "Public Key"); else pkey = load_key(bio_err, infile, informat, 1, passin, e, "key"); if (!pkey) goto end; if (!noout) { if (outformat == FORMAT_PEM) { if (pubout) PEM_write_bio_PUBKEY(out, pkey); else PEM_write_bio_PrivateKey(out, pkey, cipher, NULL, 0, NULL, passout); } else if (outformat == FORMAT_ASN1) { if (pubout) i2d_PUBKEY_bio(out, pkey); else i2d_PrivateKey_bio(out, pkey); } else { BIO_printf(bio_err, "Bad format specified for key\n"); goto end; } } if (text) { if (pubtext) EVP_PKEY_print_public(out, pkey, 0, NULL); else EVP_PKEY_print_private(out, pkey, 0, NULL); } ret = 0; end: EVP_PKEY_free(pkey); BIO_free_all(out); BIO_free(in); if (passin) OPENSSL_free(passin); if (passout) OPENSSL_free(passout); return ret; }
int genpkey_main(int argc, char **argv) { ENGINE *e = NULL; char **args, *outfile = NULL; char *passarg = NULL; BIO *in = NULL, *out = NULL; const EVP_CIPHER *cipher = NULL; int outformat; int text = 0; EVP_PKEY *pkey = NULL; EVP_PKEY_CTX *ctx = NULL; char *pass = NULL; int badarg = 0; int ret = 1, rv; int do_param = 0; outformat = FORMAT_PEM; args = argv + 1; while (!badarg && *args && *args[0] == '-') { if (!strcmp(*args, "-outform")) { if (args[1]) { args++; outformat = str2fmt(*args); } else badarg = 1; } else if (!strcmp(*args, "-pass")) { if (!args[1]) goto bad; passarg = *(++args); } #ifndef OPENSSL_NO_ENGINE else if (strcmp(*args, "-engine") == 0) { if (!args[1]) goto bad; e = setup_engine(bio_err, *(++args), 0); } #endif else if (!strcmp(*args, "-paramfile")) { if (!args[1]) goto bad; args++; if (do_param == 1) goto bad; if (!init_keygen_file(bio_err, &ctx, *args, e)) goto end; } else if (!strcmp(*args, "-out")) { if (args[1]) { args++; outfile = *args; } else badarg = 1; } else if (strcmp(*args, "-algorithm") == 0) { if (!args[1]) goto bad; if (!init_gen_str(bio_err, &ctx, *(++args), e, do_param)) goto end; } else if (strcmp(*args, "-pkeyopt") == 0) { if (!args[1]) goto bad; if (!ctx) { BIO_puts(bio_err, "No keytype specified\n"); goto bad; } else if (pkey_ctrl_string(ctx, *(++args)) <= 0) { BIO_puts(bio_err, "parameter setting error\n"); ERR_print_errors(bio_err); goto end; } } else if (strcmp(*args, "-genparam") == 0) { if (ctx) goto bad; do_param = 1; } else if (strcmp(*args, "-text") == 0) text = 1; else { cipher = EVP_get_cipherbyname(*args + 1); if (!cipher) { BIO_printf(bio_err, "Unknown cipher %s\n", *args + 1); badarg = 1; } if (do_param == 1) badarg = 1; } args++; } if (!ctx) badarg = 1; if (badarg) { bad: BIO_printf(bio_err, "Usage: genpkey [options]\n"); BIO_printf(bio_err, "where options may be\n"); BIO_printf(bio_err, "-out file output file\n"); BIO_printf(bio_err, "-outform X output format (DER or PEM)\n"); BIO_printf(bio_err, "-pass arg output file pass phrase source\n"); BIO_printf(bio_err, "-<cipher> use cipher <cipher> to encrypt the key\n"); #ifndef OPENSSL_NO_ENGINE BIO_printf(bio_err, "-engine e use engine e, possibly a hardware device.\n"); #endif BIO_printf(bio_err, "-paramfile file parameters file\n"); BIO_printf(bio_err, "-algorithm alg the public key algorithm\n"); BIO_printf(bio_err, "-pkeyopt opt:value set the public key algorithm option <opt>\n" " to value <value>\n"); BIO_printf(bio_err, "-genparam generate parameters, not key\n"); BIO_printf(bio_err, "-text print the in text\n"); BIO_printf(bio_err, "NB: options order may be important! See the manual page.\n"); goto end; } if (!app_passwd(bio_err, passarg, NULL, &pass, NULL)) { BIO_puts(bio_err, "Error getting password\n"); goto end; } if (outfile) { if (!(out = BIO_new_file(outfile, "wb"))) { BIO_printf(bio_err, "Can't open output file %s\n", outfile); goto end; } } else { out = BIO_new_fp(stdout, BIO_NOCLOSE); } EVP_PKEY_CTX_set_cb(ctx, genpkey_cb); EVP_PKEY_CTX_set_app_data(ctx, bio_err); if (do_param) { if (EVP_PKEY_paramgen(ctx, &pkey) <= 0) { BIO_puts(bio_err, "Error generating parameters\n"); ERR_print_errors(bio_err); goto end; } } else { if (EVP_PKEY_keygen(ctx, &pkey) <= 0) { BIO_puts(bio_err, "Error generating key\n"); ERR_print_errors(bio_err); goto end; } } if (do_param) rv = PEM_write_bio_Parameters(out, pkey); else if (outformat == FORMAT_PEM) rv = PEM_write_bio_PrivateKey(out, pkey, cipher, NULL, 0, NULL, pass); else if (outformat == FORMAT_ASN1) rv = i2d_PrivateKey_bio(out, pkey); else { BIO_printf(bio_err, "Bad format specified for key\n"); goto end; } if (rv <= 0) { BIO_puts(bio_err, "Error writing key\n"); ERR_print_errors(bio_err); } if (text) { if (do_param) rv = EVP_PKEY_print_params(out, pkey, 0, NULL); else rv = EVP_PKEY_print_private(out, pkey, 0, NULL); if (rv <= 0) { BIO_puts(bio_err, "Error printing key\n"); ERR_print_errors(bio_err); } } ret = 0; end: if (pkey) EVP_PKEY_free(pkey); if (ctx) EVP_PKEY_CTX_free(ctx); if (out) BIO_free_all(out); BIO_free(in); free(pass); return ret; }
static int process(const char *uri, const UI_METHOD *uimeth, PW_CB_DATA *uidata, int text, int noout, int recursive, int indent, BIO *out) { OSSL_STORE_CTX *store_ctx = NULL; int ret = 1, items = 0; if ((store_ctx = OSSL_STORE_open(uri, uimeth, uidata, NULL, NULL)) == NULL) { BIO_printf(bio_err, "Couldn't open file or uri %s\n", uri); ERR_print_errors(bio_err); return ret; } /* From here on, we count errors, and we'll return the count at the end */ ret = 0; for (;;) { OSSL_STORE_INFO *info = OSSL_STORE_load(store_ctx); int type = info == NULL ? 0 : OSSL_STORE_INFO_get_type(info); const char *infostr = info == NULL ? NULL : OSSL_STORE_INFO_type_string(type); if (info == NULL) { if (OSSL_STORE_eof(store_ctx)) break; if (OSSL_STORE_error(store_ctx)) { if (recursive) ERR_clear_error(); else ERR_print_errors(bio_err); ret++; continue; } BIO_printf(bio_err, "ERROR: OSSL_STORE_load() returned NULL without " "eof or error indications\n"); BIO_printf(bio_err, " This is an error in the loader\n"); ERR_print_errors(bio_err); ret++; break; } if (type == OSSL_STORE_INFO_NAME) { const char *name = OSSL_STORE_INFO_get0_NAME(info); const char *desc = OSSL_STORE_INFO_get0_NAME_description(info); indent_printf(indent, bio_out, "%d: %s: %s\n", items, infostr, name); if (desc != NULL) indent_printf(indent, bio_out, "%s\n", desc); } else { indent_printf(indent, bio_out, "%d: %s\n", items, infostr); } /* * Unfortunately, PEM_X509_INFO_write_bio() is sorely lacking in * functionality, so we must figure out how exactly to write things * ourselves... */ switch (type) { case OSSL_STORE_INFO_NAME: if (recursive) { const char *suburi = OSSL_STORE_INFO_get0_NAME(info); ret += process(suburi, uimeth, uidata, text, noout, recursive, indent + 2, out); } break; case OSSL_STORE_INFO_PARAMS: if (text) EVP_PKEY_print_params(out, OSSL_STORE_INFO_get0_PARAMS(info), 0, NULL); if (!noout) PEM_write_bio_Parameters(out, OSSL_STORE_INFO_get0_PARAMS(info)); break; case OSSL_STORE_INFO_PKEY: if (text) EVP_PKEY_print_private(out, OSSL_STORE_INFO_get0_PKEY(info), 0, NULL); if (!noout) PEM_write_bio_PrivateKey(out, OSSL_STORE_INFO_get0_PKEY(info), NULL, NULL, 0, NULL, NULL); break; case OSSL_STORE_INFO_CERT: if (text) X509_print(out, OSSL_STORE_INFO_get0_CERT(info)); if (!noout) PEM_write_bio_X509(out, OSSL_STORE_INFO_get0_CERT(info)); break; case OSSL_STORE_INFO_CRL: if (text) X509_CRL_print(out, OSSL_STORE_INFO_get0_CRL(info)); if (!noout) PEM_write_bio_X509_CRL(out, OSSL_STORE_INFO_get0_CRL(info)); break; default: BIO_printf(bio_err, "!!! Unknown code\n"); ret++; break; } items++; OSSL_STORE_INFO_free(info); } indent_printf(indent, out, "Total found: %d\n", items); if (!OSSL_STORE_close(store_ctx)) { ERR_print_errors(bio_err); ret++; } return ret; }
DDS_ReturnCode_t sp_extract_pem (DDS_Credentials *cred, unsigned char **cert, size_t *cert_len, unsigned char **key, size_t *key_len) { BIO *cert_in, *key_in; int i; FILE *fp; long lSize; if (cred->credentialKind == DDS_ENGINE_BASED) { /* Not implemented */ } else if (cred->credentialKind == DDS_FILE_BASED) { /* Read the certificate pem file */ fp = fopen ( cred->info.filenames.certificate_chain_file , "rb" ); if( !fp ) perror ( cred->info.filenames.certificate_chain_file),exit(1); fseek ( fp , 0L , SEEK_END); lSize = ftell( fp ); rewind ( fp ); *cert = calloc ( 1, lSize+1 ); if( !*cert ) fclose(fp),fputs("memory alloc fails",stderr),exit(1); if( 1!=fread( (void *) *cert , lSize, 1 , fp) ) fclose(fp),free(*cert),fputs("entire read fails",stderr),exit(1); *cert_len = (size_t) lSize; fclose(fp); /* Read private key pem file */ fp = fopen (cred->info.filenames.private_key_file, "rb" ); if (!fp) { perror (cred->info.filenames.private_key_file); exit(1); } fseek ( fp , 0L , SEEK_END); lSize = ftell( fp ); rewind ( fp ); *key = calloc ( 1, lSize+1 ); if( !*key ) fclose(fp),fputs("memory alloc fails",stderr),exit(1); if( 1!=fread( (void *) *key , lSize, 1 , fp) ) fclose(fp),free(*key),fputs("entire read fails",stderr),exit(1); *key_len = (size_t) lSize; fclose(fp); } else if (cred->credentialKind == DDS_SSL_BASED) { cert_in = BIO_new (BIO_s_mem ()); key_in = BIO_new (BIO_s_mem ()); /* Write the X509 to a PEM format in a BIO */ for (i = 0; i < sk_X509_num (cred->info.sslData.certificate_list); i++) PEM_write_bio_X509(cert_in, sk_X509_value (cred->info.sslData.certificate_list, i)); *cert = malloc (sizeof (unsigned char) * cert_in->num_write + 1); /* read from the BIO into a char * */ *cert_len = BIO_read (cert_in, *cert, cert_in->num_write); memset (&(*cert) [(int) *cert_len], '\0', sizeof (char)); /* Write the X509 to a PEM format in a BIO */ PEM_write_bio_PrivateKey(key_in, cred->info.sslData.private_key, NULL, NULL, 0, 0, NULL); *key = malloc (sizeof (unsigned char) * key_in->num_write + 1); /* read from the BIO into a char * */ *key_len = BIO_read (key_in, *key, key_in->num_write); memset (&(*key) [(int) *key_len], '\0', sizeof (char)); BIO_free (cert_in); BIO_free (key_in); } else if (cred->credentialKind == DDS_DATA_BASED) { if (cred->info.data.private_key.format == DDS_FORMAT_PEM) { *key = malloc (sizeof (unsigned char) * cred->info.data.private_key.length + 1); strcpy ((char *) *key, (char *) cred->info.data.private_key.data); *key_len = cred->info.data.private_key.length; } else { /* Not implemented */ } /* This is okay for the current useage, but not for the intended useage */ for (i = 0; i < (int) cred->info.data.num_certificates ; i++) { if (cred->info.data.certificates [i].format == DDS_FORMAT_PEM) { *cert = malloc (sizeof (unsigned char) * cred->info.data.certificates [i].length + 1); strcpy ((char *) *cert, (char *) cred->info.data.certificates [i].data); *cert_len = cred->info.data.certificates [i].length; } } } else { /*TODO: Go get the cert from data*/ } return (DDS_RETCODE_OK); }
uint8_t * tls_load_file(const char *name, size_t *len, char *password) { FILE *fp; EVP_PKEY *key = NULL; BIO *bio = NULL; char *data; uint8_t *buf = NULL; struct stat st; size_t size = 0; int fd = -1; ssize_t n; *len = 0; if ((fd = open(name, O_RDONLY)) == -1) return (NULL); /* Just load the file into memory without decryption */ if (password == NULL) { if (fstat(fd, &st) != 0) goto fail; if (st.st_size < 0) goto fail; size = (size_t)st.st_size; if ((buf = malloc(size)) == NULL) goto fail; n = read(fd, buf, size); if (n < 0 || (size_t)n != size) goto fail; close(fd); goto done; } /* Or read the (possibly) encrypted key from file */ if ((fp = fdopen(fd, "r")) == NULL) goto fail; fd = -1; key = PEM_read_PrivateKey(fp, NULL, tls_password_cb, password); fclose(fp); if (key == NULL) goto fail; /* Write unencrypted key to memory buffer */ if ((bio = BIO_new(BIO_s_mem())) == NULL) goto fail; if (!PEM_write_bio_PrivateKey(bio, key, NULL, NULL, 0, NULL, NULL)) goto fail; if ((size = BIO_get_mem_data(bio, &data)) <= 0) goto fail; if ((buf = malloc(size)) == NULL) goto fail; memcpy(buf, data, size); BIO_free_all(bio); EVP_PKEY_free(key); done: *len = size; return (buf); fail: if (fd != -1) close(fd); freezero(buf, size); BIO_free_all(bio); EVP_PKEY_free(key); return (NULL); }
int pkey_main(int argc, char **argv) { char **args, *infile = NULL, *outfile = NULL; char *passargin = NULL, *passargout = NULL; BIO *in = NULL, *out = NULL; const EVP_CIPHER *cipher = NULL; int informat, outformat; int pubin = 0, pubout = 0, pubtext = 0, text = 0, noout = 0; EVP_PKEY *pkey = NULL; char *passin = NULL, *passout = NULL; int badarg = 0; int ret = 1; if (single_execution) { if (pledge("stdio rpath wpath cpath tty", NULL) == -1) { perror("pledge"); exit(1); } } informat = FORMAT_PEM; outformat = FORMAT_PEM; args = argv + 1; while (!badarg && *args && *args[0] == '-') { if (!strcmp(*args, "-inform")) { if (args[1]) { args++; informat = str2fmt(*args); } else badarg = 1; } else if (!strcmp(*args, "-outform")) { if (args[1]) { args++; outformat = str2fmt(*args); } else badarg = 1; } else if (!strcmp(*args, "-passin")) { if (!args[1]) goto bad; passargin = *(++args); } else if (!strcmp(*args, "-passout")) { if (!args[1]) goto bad; passargout = *(++args); } 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, "-pubin") == 0) { pubin = 1; pubout = 1; pubtext = 1; } else if (strcmp(*args, "-pubout") == 0) pubout = 1; else if (strcmp(*args, "-text_pub") == 0) { pubtext = 1; text = 1; } else if (strcmp(*args, "-text") == 0) text = 1; else if (strcmp(*args, "-noout") == 0) noout = 1; else { cipher = EVP_get_cipherbyname(*args + 1); if (!cipher) { BIO_printf(bio_err, "Unknown cipher %s\n", *args + 1); badarg = 1; } } args++; } if (badarg) { bad: BIO_printf(bio_err, "Usage pkey [options]\n"); BIO_printf(bio_err, "where options are\n"); BIO_printf(bio_err, "-in file input file\n"); BIO_printf(bio_err, "-inform X input format (DER or PEM)\n"); BIO_printf(bio_err, "-passin arg input file pass phrase source\n"); BIO_printf(bio_err, "-outform X output format (DER or PEM)\n"); BIO_printf(bio_err, "-out file output file\n"); BIO_printf(bio_err, "-passout arg output file pass phrase source\n"); return 1; } if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) { BIO_printf(bio_err, "Error getting passwords\n"); goto end; } if (outfile) { if (!(out = BIO_new_file(outfile, "wb"))) { BIO_printf(bio_err, "Can't open output file %s\n", outfile); goto end; } } else { out = BIO_new_fp(stdout, BIO_NOCLOSE); } if (pubin) pkey = load_pubkey(bio_err, infile, informat, 1, passin, "Public Key"); else pkey = load_key(bio_err, infile, informat, 1, passin, "key"); if (!pkey) goto end; if (!noout) { if (outformat == FORMAT_PEM) { if (pubout) PEM_write_bio_PUBKEY(out, pkey); else PEM_write_bio_PrivateKey(out, pkey, cipher, NULL, 0, NULL, passout); } else if (outformat == FORMAT_ASN1) { if (pubout) i2d_PUBKEY_bio(out, pkey); else i2d_PrivateKey_bio(out, pkey); } else { BIO_printf(bio_err, "Bad format specified for key\n"); goto end; } } if (text) { if (pubtext) EVP_PKEY_print_public(out, pkey, 0, NULL); else EVP_PKEY_print_private(out, pkey, 0, NULL); } ret = 0; end: EVP_PKEY_free(pkey); BIO_free_all(out); BIO_free(in); free(passin); free(passout); return ret; }
static EP_STAT key_write_bio(EP_CRYPTO_KEY *key, BIO *bio, int keyform, int keyenc, const char *passwd, uint32_t flags) { const char *pubsec = EP_UT_BITSET(EP_CRYPTO_F_SECRET, flags) ? "secret" : "public"; int istat; EP_ASSERT(bio != NULL); if (keyform <= 0) { (void) _ep_crypto_error("keyform must be specified"); return EP_STAT_CRYPTO_CONVERT; } if (keyform == EP_CRYPTO_KEYFORM_PEM) { // easy case if (EP_UT_BITSET(EP_CRYPTO_F_SECRET, flags)) { const EVP_CIPHER *enc = cipher_byid(keyenc); istat = PEM_write_bio_PrivateKey(bio, key, enc, NULL, 0, NULL, (void *) passwd); } else { istat = PEM_write_bio_PUBKEY(bio, key); } if (istat != 1) { (void) _ep_crypto_error("cannot write %s PEM key", pubsec); return EP_STAT_CRYPTO_CONVERT; } goto finis; } #if _EP_CRYPTO_INCLUDE_DER else if (keyform == EP_CRYPTO_KEYFORM_DER) { if (EP_UT_BITSET(EP_CRYPTO_F_SECRET, flags)) { if (keyenc != EP_CRYPTO_SYMKEY_NONE && ep_dbg_test(Dbg, 1)) { ep_dbg_printf("WARNING: writing unencrypted " "private key DER file\n"); } istat = i2d_PrivateKey_bio(bio, key); } else { istat = i2d_PUBKEY_bio(bio, key); } if (istat != 1) { (void) _ep_crypto_error("cannot write %s DER key", pubsec); return EP_STAT_CRYPTO_CONVERT; } } #endif // _EP_CRYPTO_INCLUDE_DER else { (void) _ep_crypto_error("unknown key format %d", keyform); return EP_STAT_CRYPTO_KEYFORM; } finis: return EP_STAT_FROM_INT(BIO_ctrl_pending(bio)); }