void pki_x509req::createReq(pki_key *key, const x509name &dn, const EVP_MD *md, extList el) { int bad_nids[] = { NID_subject_key_identifier, NID_authority_key_identifier, NID_issuer_alt_name, NID_undef }; EVP_PKEY *privkey = NULL; if (key->isPubKey()) { my_error(tr("Signing key not valid (public key)")); return; } X509_REQ_set_version(request, 0L); X509_REQ_set_pubkey(request, key->getPubKey()); setSubject(dn); pki_openssl_error(); for(int i=0; bad_nids[i] != NID_undef; i++) el.delByNid(bad_nids[i]); el.delInvalid(); if (el.count() > 0) { STACK_OF(X509_EXTENSION) *sk; sk = el.getStack(); X509_REQ_add_extensions(request, sk); sk_X509_EXTENSION_pop_free(sk, X509_EXTENSION_free); } pki_openssl_error(); privkey = key->decryptKey(); X509_REQ_sign(request, privkey, md); pki_openssl_error(); EVP_PKEY_free(privkey); }
/* * Routine used to CSR for est_client_enroll_csr testcases */ static int populate_x509_csr (X509_REQ *req, EVP_PKEY *pkey, char *cn) { X509_NAME *subj; /* Setup version number */ if (!X509_REQ_set_version(req, 0L)) { printf("\nUnable to set X509 version#\n"); return (-1); } /* * Add Common Name entry */ subj = X509_REQ_get_subject_name(req); if (!X509_NAME_add_entry_by_txt(subj, "CN", MBSTRING_ASC, (unsigned char*)cn, -1, -1, 0)) { printf("\nUnable to create X509 Common Name entry\n"); return (-1); } /* * Set the public key on the request */ if (!X509_REQ_set_pubkey(req, pkey)) { printf("\nUnable to set X509 public key\n"); return (-1); } return (0); }
/*** create or generate a new x509_req object. Note if not give evp_pkey, will create a new x509_req object,or will generate a signed x509_req object. @function new @tparam[opt] x509_name subject subject name set to x509_req @tparam[opt] stack_of_x509_extension extensions add to x509_req @tparam[opt] stack_of_x509_attribute attributes add to x509_req @tparam[opt] evp_pkey pkey private key sign the x509_req, and set as public key @tparam[opt='sha1WithRSAEncryption'] evp_digest|string md_alg, only used when pkey exist, and should fellow pkey @treturn x509_req certificate sign request object @see x509_req */ static LUA_FUNCTION(openssl_csr_new) { X509_REQ *csr = X509_REQ_new(); int i; int n = lua_gettop(L); int ret = X509_REQ_set_version(csr, 0L); for (i = 1; ret == 1 && i <= n; i++) { luaL_argcheck(L, auxiliar_getclassudata(L, "openssl.x509_name", i) || auxiliar_getclassudata(L, "openssl.evp_pkey", i), i, "must be x509_name or evp_pkey"); if (auxiliar_getclassudata(L, "openssl.x509_name", i)) { X509_NAME * subject = CHECK_OBJECT(i, X509_NAME, "openssl.x509_name"); ret = X509_REQ_set_subject_name(csr, subject); } if (auxiliar_getclassudata(L, "openssl.evp_pkey", i)) { EVP_PKEY *pkey; const EVP_MD *md; luaL_argcheck(L, i == n || i == n - 1, i, "must is evp_pkey object"); pkey = CHECK_OBJECT(i, EVP_PKEY, "openssl.evp_pkey"); if (i == n - 1) md = get_digest(L, n, NULL); else md = EVP_get_digestbyname("sha256"); ret = X509_REQ_set_pubkey(csr, pkey); if (ret == 1) { ret = X509_REQ_sign(csr, pkey, md); if (ret > 0) ret = 1; } break; } }; if (ret == 1) PUSH_OBJECT(csr, "openssl.x509_req"); else { X509_REQ_free(csr); return openssl_pushresult(L, ret); } return 1; }
static gboolean ConfigX509CertReq(X509_REQ *req, // OUT CONF *config) // IN { int idx; X509_NAME *subject; gboolean ret = FALSE; const char *dname; gchar *err = NULL; if (!X509_REQ_set_version(req, 0L)) { Error("Failed to set the certificate request version: %s.\n", GetSSLError(&err)); goto exit; } subject = X509_REQ_get_subject_name(req); if (!subject) { Error("Failed to get the certificate request subject name: %s.\n", GetSSLError(&err)); goto exit; } dname = NCONF_get_string(config, "req", "distinguished_name"); if (dname) { STACK_OF(CONF_VALUE) *dn_sk = NCONF_get_section(config, dname); if (!dn_sk) { Error("Failed to get section %s: %s.\n", dname, GetSSLError(&err)); goto exit; } for (idx = 0; idx < sk_CONF_VALUE_num(dn_sk); idx++) { CONF_VALUE *v = sk_CONF_VALUE_value(dn_sk, idx); if (!X509_NAME_add_entry_by_txt(subject, v->name, MBSTRING_ASC, v->value, -1, -1, 0)) { Error("Failed to set certificate request pair %s/%s: %s.\n", v->name, v->value, GetSSLError(&err)); goto exit; } } } ret = TRUE; exit: g_free(err); return ret; }
static LUA_FUNCTION(openssl_csr_version) { X509_REQ *csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req"); if (lua_isnone(L, 2)) { lua_pushinteger(L, X509_REQ_get_version(csr)); return 1; } else { long version = luaL_checkint(L, 2); int ret = X509_REQ_set_version(csr, version); return openssl_pushresult(L, ret); } }
int MakeX509CSR(const char *cn, const char *keyfile, const char *csrfile) { InitializeOpenSSL(); RSA *rsa = RSA_generate_key(4096, RSA_F4, NULL, NULL); BIO *bio = BIO_new(BIO_s_file()); BIO_write_filename(bio, const_cast<char *>(keyfile)); PEM_write_bio_RSAPrivateKey(bio, rsa, NULL, NULL, 0, NULL, NULL); BIO_free(bio); X509_REQ *req = X509_REQ_new(); if (!req) return 0; EVP_PKEY *key = EVP_PKEY_new(); EVP_PKEY_assign_RSA(key, rsa); X509_REQ_set_version(req, 0); X509_REQ_set_pubkey(req, key); X509_NAME *name = X509_REQ_get_subject_name(req); X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (unsigned char *)cn, -1, -1, 0); X509_REQ_sign(req, key, EVP_sha1()); EVP_PKEY_free(key); bio = BIO_new(BIO_s_file()); BIO_write_filename(bio, const_cast<char *>(csrfile)); PEM_write_bio_X509_REQ(bio, req); BIO_free(bio); X509_REQ_free(req); return 1; }
int generate_csr(char** pem_csr) { FILE* fp; RSA * rsa_priv_key; int ret = 0; int nVersion = 0; int keylen = 0; X509_REQ *x509_req = NULL; X509_NAME *x509_name = NULL; EVP_PKEY *pKey = NULL; BIO *bio = NULL; // 2. set version of x509 req x509_req = X509_REQ_new(); ret = X509_REQ_set_version(x509_req, nVersion); if (ret != 1) { goto free_all; } // 3. set subject of x509 req x509_name = X509_REQ_get_subject_name(x509_req); ret = X509_NAME_add_entry_by_txt(x509_name, "C", V_ASN1_PRINTABLESTRING, (const unsigned char*) szCountry, -1, -1, 0); if (ret != 1) { goto free_all; } ret = X509_NAME_add_entry_by_txt(x509_name, "ST", V_ASN1_PRINTABLESTRING, (const unsigned char*) szProvince, -1, -1, 0); if (ret != 1) { goto free_all; } ret = X509_NAME_add_entry_by_txt(x509_name, "L", V_ASN1_PRINTABLESTRING, (const unsigned char*) szCity, -1, -1, 0); if (ret != 1) { goto free_all; } ret = X509_NAME_add_entry_by_txt(x509_name, "O", V_ASN1_PRINTABLESTRING, (const unsigned char*) api_company, -1, -1, 0); if (ret != 1) { goto free_all; } ret = X509_NAME_add_entry_by_txt(x509_name, "OU", V_ASN1_PRINTABLESTRING, (const unsigned char*) szOrganization, -1, -1, 0); if (ret != 1) { goto free_all; } ret = X509_NAME_add_entry_by_txt(x509_name, "CN", V_ASN1_PRINTABLESTRING, (const unsigned char*) szCommon, -1, -1, 0); if (ret != 1) { goto free_all; } ret = X509_NAME_add_entry_by_txt(x509_name, "emailAddress", V_ASN1_IA5STRING, (const unsigned char*) szEmail, -1, -1, 0); if (ret != 1) { goto free_all; } ret = X509_NAME_add_entry_by_txt(x509_name, "challengePassword", V_ASN1_PRINTABLESTRING, (const unsigned char*) szChallengePassword, -1, -1, 0); if (ret != 1) { goto free_all; } // 4. set public key of x509 req if (load_rsa_pkey(&rsa_priv_key) < 0) goto free_all; pKey = EVP_PKEY_new(); EVP_PKEY_assign_RSA(pKey, rsa_priv_key); ret = X509_REQ_set_pubkey(x509_req, pKey); if (ret != 1) { goto free_all; } // 5. set sign key of x509 req ret = X509_REQ_sign(x509_req, pKey, EVP_sha1()); // return x509_req->signature->length if (ret <= 0) { goto free_all; } /* To get the C-string PEM form: */ bio = BIO_new(BIO_s_mem()); PEM_write_bio_X509_REQ(bio, x509_req); keylen = BIO_pending(bio); *pem_csr = malloc(keylen + 1); /* Null-terminate */ BIO_read(bio, *pem_csr, keylen); /* Write to file */ fp = fopen(f_csr, "w"); if (fp) { fwrite(*pem_csr, keylen, 1, fp); fclose(fp); } LOG(VERBOSE, "[API] CSR created:%s", *pem_csr); // 6. free free_all: X509_REQ_free(x509_req); BIO_free_all(bio); return (keylen); }
/* * initialize ssl engine, load certs and initialize openssl internals */ void init_ssl(void) { const SSL_METHOD *ssl_method; RSA *rsa=NULL; X509_REQ *req = NULL; X509 *cer = NULL; EVP_PKEY *pk = NULL; EVP_PKEY *req_pkey = NULL; X509_NAME *name = NULL; FILE *fp; char buf[SIZ]; int rv = 0; if (!access("/var/run/egd-pool", F_OK)) { RAND_egd("/var/run/egd-pool"); } if (!RAND_status()) { syslog(LOG_WARNING, "PRNG not adequately seeded, won't do SSL/TLS\n"); return; } SSLCritters = malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t *)); if (!SSLCritters) { syslog(LOG_ERR, "citserver: can't allocate memory!!\n"); /* Nothing's been initialized, just die */ ShutDownWebcit(); exit(WC_EXIT_SSL); } else { int a; for (a = 0; a < CRYPTO_num_locks(); a++) { SSLCritters[a] = malloc(sizeof(pthread_mutex_t)); if (!SSLCritters[a]) { syslog(LOG_EMERG, "citserver: can't allocate memory!!\n"); /** Nothing's been initialized, just die */ ShutDownWebcit(); exit(WC_EXIT_SSL); } pthread_mutex_init(SSLCritters[a], NULL); } } /* * Initialize SSL transport layer */ SSL_library_init(); SSL_load_error_strings(); ssl_method = SSLv23_server_method(); if (!(ssl_ctx = SSL_CTX_new(ssl_method))) { syslog(LOG_WARNING, "SSL_CTX_new failed: %s\n", ERR_reason_error_string(ERR_get_error())); return; } syslog(LOG_INFO, "Requesting cipher list: %s\n", ssl_cipher_list); if (!(SSL_CTX_set_cipher_list(ssl_ctx, ssl_cipher_list))) { syslog(LOG_WARNING, "SSL_CTX_set_cipher_list failed: %s\n", ERR_reason_error_string(ERR_get_error())); return; } CRYPTO_set_locking_callback(ssl_lock); CRYPTO_set_id_callback(id_callback); /* * Get our certificates in order. (FIXME: dirify. this is a setup job.) * First, create the key/cert directory if it's not there already... */ mkdir(CTDL_CRYPTO_DIR, 0700); /* * Before attempting to generate keys/certificates, first try * link to them from the Citadel server if it's on the same host. * We ignore any error return because it either meant that there * was nothing in Citadel to link from (in which case we just * generate new files) or the target files already exist (which * is not fatal either). */ if (!strcasecmp(ctdlhost, "uds")) { sprintf(buf, "%s/keys/citadel.key", ctdlport); rv = symlink(buf, CTDL_KEY_PATH); if (!rv) syslog(LOG_DEBUG, "%s\n", strerror(errno)); sprintf(buf, "%s/keys/citadel.csr", ctdlport); rv = symlink(buf, CTDL_CSR_PATH); if (!rv) syslog(LOG_DEBUG, "%s\n", strerror(errno)); sprintf(buf, "%s/keys/citadel.cer", ctdlport); rv = symlink(buf, CTDL_CER_PATH); if (!rv) syslog(LOG_DEBUG, "%s\n", strerror(errno)); } /* * If we still don't have a private key, generate one. */ if (access(CTDL_KEY_PATH, R_OK) != 0) { syslog(LOG_INFO, "Generating RSA key pair.\n"); rsa = RSA_generate_key(1024, /* modulus size */ 65537, /* exponent */ NULL, /* no callback */ NULL /* no callback */ ); if (rsa == NULL) { syslog(LOG_WARNING, "Key generation failed: %s\n", ERR_reason_error_string(ERR_get_error())); } if (rsa != NULL) { fp = fopen(CTDL_KEY_PATH, "w"); if (fp != NULL) { chmod(CTDL_KEY_PATH, 0600); if (PEM_write_RSAPrivateKey(fp, /* the file */ rsa, /* the key */ NULL, /* no enc */ NULL, /* no passphr */ 0, /* no passphr */ NULL, /* no callbk */ NULL /* no callbk */ ) != 1) { syslog(LOG_WARNING, "Cannot write key: %s\n", ERR_reason_error_string(ERR_get_error())); unlink(CTDL_KEY_PATH); } fclose(fp); } else { syslog(LOG_WARNING, "Cannot write key: %s\n", CTDL_KEY_PATH); ShutDownWebcit(); exit(0); } RSA_free(rsa); } } /* * If there is no certificate file on disk, we will be generating a self-signed certificate * in the next step. Therefore, if we have neither a CSR nor a certificate, generate * the CSR in this step so that the next step may commence. */ if ( (access(CTDL_CER_PATH, R_OK) != 0) && (access(CTDL_CSR_PATH, R_OK) != 0) ) { syslog(LOG_INFO, "Generating a certificate signing request.\n"); /* * Read our key from the file. No, we don't just keep this * in memory from the above key-generation function, because * there is the possibility that the key was already on disk * and we didn't just generate it now. */ fp = fopen(CTDL_KEY_PATH, "r"); if (fp) { rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL); fclose(fp); } if (rsa) { /** Create a public key from the private key */ if (pk=EVP_PKEY_new(), pk != NULL) { EVP_PKEY_assign_RSA(pk, rsa); if (req = X509_REQ_new(), req != NULL) { const char *env; /* Set the public key */ X509_REQ_set_pubkey(req, pk); X509_REQ_set_version(req, 0L); name = X509_REQ_get_subject_name(req); /* Tell it who we are */ /* * We used to add these fields to the subject, but * now we don't. Someone doing this for real isn't * going to use the webcit-generated CSR anyway. * X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC, "US", -1, -1, 0); * X509_NAME_add_entry_by_txt(name, "ST", MBSTRING_ASC, "New York", -1, -1, 0); * X509_NAME_add_entry_by_txt(name, "L", MBSTRING_ASC, "Mount Kisco", -1, -1, 0); */ env = getenv("O"); if (env == NULL) env = "Organization name", X509_NAME_add_entry_by_txt( name, "O", MBSTRING_ASC, (unsigned char*)env, -1, -1, 0 ); env = getenv("OU"); if (env == NULL) env = "Citadel server"; X509_NAME_add_entry_by_txt( name, "OU", MBSTRING_ASC, (unsigned char*)env, -1, -1, 0 ); env = getenv("CN"); if (env == NULL) env = "*"; X509_NAME_add_entry_by_txt( name, "CN", MBSTRING_ASC, (unsigned char*)env, -1, -1, 0 ); X509_REQ_set_subject_name(req, name); /* Sign the CSR */ if (!X509_REQ_sign(req, pk, EVP_md5())) { syslog(LOG_WARNING, "X509_REQ_sign(): error\n"); } else { /* Write it to disk. */ fp = fopen(CTDL_CSR_PATH, "w"); if (fp != NULL) { chmod(CTDL_CSR_PATH, 0600); PEM_write_X509_REQ(fp, req); fclose(fp); } else { syslog(LOG_WARNING, "Cannot write key: %s\n", CTDL_CSR_PATH); ShutDownWebcit(); exit(0); } } X509_REQ_free(req); } } RSA_free(rsa); } else { syslog(LOG_WARNING, "Unable to read private key.\n"); } } /* * Generate a self-signed certificate if we don't have one. */ if (access(CTDL_CER_PATH, R_OK) != 0) { syslog(LOG_INFO, "Generating a self-signed certificate.\n"); /* Same deal as before: always read the key from disk because * it may or may not have just been generated. */ fp = fopen(CTDL_KEY_PATH, "r"); if (fp) { rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL); fclose(fp); } /* This also holds true for the CSR. */ req = NULL; cer = NULL; pk = NULL; if (rsa) { if (pk=EVP_PKEY_new(), pk != NULL) { EVP_PKEY_assign_RSA(pk, rsa); } fp = fopen(CTDL_CSR_PATH, "r"); if (fp) { req = PEM_read_X509_REQ(fp, NULL, NULL, NULL); fclose(fp); } if (req) { if (cer = X509_new(), cer != NULL) { ASN1_INTEGER_set(X509_get_serialNumber(cer), 0); X509_set_issuer_name(cer, req->req_info->subject); X509_set_subject_name(cer, req->req_info->subject); X509_gmtime_adj(X509_get_notBefore(cer), 0); X509_gmtime_adj(X509_get_notAfter(cer),(long)60*60*24*SIGN_DAYS); req_pkey = X509_REQ_get_pubkey(req); X509_set_pubkey(cer, req_pkey); EVP_PKEY_free(req_pkey); /* Sign the cert */ if (!X509_sign(cer, pk, EVP_md5())) { syslog(LOG_WARNING, "X509_sign(): error\n"); } else { /* Write it to disk. */ fp = fopen(CTDL_CER_PATH, "w"); if (fp != NULL) { chmod(CTDL_CER_PATH, 0600); PEM_write_X509(fp, cer); fclose(fp); } else { syslog(LOG_WARNING, "Cannot write key: %s\n", CTDL_CER_PATH); ShutDownWebcit(); exit(0); } } X509_free(cer); } } RSA_free(rsa); } } /* * Now try to bind to the key and certificate. * Note that we use SSL_CTX_use_certificate_chain_file() which allows * the certificate file to contain intermediate certificates. */ SSL_CTX_use_certificate_chain_file(ssl_ctx, CTDL_CER_PATH); SSL_CTX_use_PrivateKey_file(ssl_ctx, CTDL_KEY_PATH, SSL_FILETYPE_PEM); if ( !SSL_CTX_check_private_key(ssl_ctx) ) { syslog(LOG_WARNING, "Cannot install certificate: %s\n", ERR_reason_error_string(ERR_get_error())); } }
wi_x509_t * wi_x509_init_with_common_name(wi_x509_t *x509, wi_rsa_t *rsa, wi_string_t *common_name) { X509_REQ *req; EVP_PKEY *pkey = NULL; X509_NAME *name = NULL; BIGNUM *bn = NULL; req = X509_REQ_new(); if(!req) goto err; if(X509_REQ_set_version(req, 0) != 1) goto err; name = X509_NAME_new(); if(X509_NAME_add_entry_by_NID(name, NID_commonName, MBSTRING_ASC, (unsigned char *) wi_string_cstring(common_name), -1, -1, 0) != 1) goto err; if(X509_REQ_set_subject_name(req, name) != 1) goto err; pkey = EVP_PKEY_new(); EVP_PKEY_set1_RSA(pkey, wi_rsa_rsa(rsa)); if(X509_REQ_set_pubkey(req, pkey) != 1) goto err; x509->x509 = X509_new(); if(!x509->x509) goto err; bn = BN_new(); if(!bn) goto err; if(BN_pseudo_rand(bn, 64, 0, 0) != 1) goto err; if(!BN_to_ASN1_INTEGER(bn, X509_get_serialNumber(x509->x509))) goto err; if(X509_set_issuer_name(x509->x509, X509_REQ_get_subject_name(req)) != 1) goto err; if(!X509_gmtime_adj(X509_get_notBefore(x509->x509), 0)) goto err; if(!X509_gmtime_adj(X509_get_notAfter(x509->x509), 3600 * 24 * 365)) goto err; if(X509_set_subject_name(x509->x509, X509_REQ_get_subject_name(req)) != 1) goto end; if(X509_set_pubkey(x509->x509, pkey) != 1) goto err; if(X509_sign(x509->x509, pkey, EVP_sha1()) == 0) goto err; goto end; err: wi_error_set_openssl_error(); wi_release(x509); x509 = NULL; end: if(req) X509_REQ_free(req); if(pkey) EVP_PKEY_free(pkey); if(name) X509_NAME_free(name); if(bn) BN_free(bn); return x509; }
TokenError _backend_createRequest(const RegutilInfo *info, const char *hostname, const char *password, char **request, size_t *reqlen) { // OpenSSL seeds the PRNG automatically, see the manual page for RAND_add. if (!RAND_status()) { fprintf(stderr, BINNAME ": no random state!\n"); return TokenError_NoRandomState; } // Abort if there are no requests *request = NULL; if (!info->pkcs10) return TokenError_Unknown; // Create certificate requests bool ok = true; CertReq *reqs = NULL; STACK *x509reqs = sk_new_null(); for (const RegutilPKCS10 *pkcs10 = info->pkcs10; pkcs10 != NULL; pkcs10 = pkcs10->next) { RSA *rsa = NULL; EVP_PKEY *privkey = NULL; X509_NAME *subject = NULL; X509_REQ *x509req = NULL; STACK_OF(X509_EXTENSION) *exts = NULL; // Check the parameters. // Maximum key size in OpenSSL: // http://www.mail-archive.com/[email protected]/msg58229.html if (!pkcs10->subjectDN || pkcs10->keySize < 1024 || pkcs10->keySize > 16384) goto req_error; // Generate key pair // FIXME deprecated function // TODO use OPENSSL_NO_DEPRECATED rsa = RSA_generate_key(pkcs10->keySize, RSA_F4, NULL, NULL); if (!rsa) goto req_error; privkey = EVP_PKEY_new(); if (!privkey) goto req_error; EVP_PKEY_assign_RSA(privkey, rsa); // Subject name subject = certutil_parse_dn(pkcs10->subjectDN, pkcs10->includeFullDN); if (!subject) goto req_error; // Create request x509req = X509_REQ_new(); if (!x509req || !X509_REQ_set_version(x509req, 0) || !X509_REQ_set_subject_name(x509req, subject) || !X509_REQ_set_pubkey(x509req, privkey)) { // yes this is correct(!) certutil_updateErrorString(); goto req_error; } // Set attributes exts = sk_X509_EXTENSION_new_null(); if (!exts) goto req_error; X509_EXTENSION *ext = makeKeyUsageExt(pkcs10->keyUsage); if (!ext || !sk_X509_EXTENSION_push(exts, ext)) goto req_error; if (!X509_REQ_add_extensions(x509req, exts)) { certutil_updateErrorString(); goto req_error; } exts = NULL; // Add signature if (!X509_REQ_sign(x509req, privkey, EVP_sha1())) { certutil_updateErrorString(); goto req_error; } // Store in list CertReq *req = malloc(sizeof(CertReq)); req->pkcs10 = pkcs10; req->privkey = privkey; req->rsa = rsa; req->x509 = x509req; req->next = reqs; reqs = req; sk_push(x509reqs, (char*)x509req); continue; req_error: // Clean up and set error flag if (privkey) EVP_PKEY_free(privkey); else if (rsa) RSA_free(rsa); X509_NAME_free(subject); sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); X509_REQ_free(x509req); ok = false; } TokenError error = TokenError_Unknown; if (ok) { // Determine filename from certificate name char *filename = certutil_makeFilename(X509_REQ_get_subject_name(reqs->x509)); // Build the certificate request request_wrap(x509reqs, request, reqlen); if (*request && filename) { // Create the key file in ~/cbt/name.p12 FILE *keyfile = platform_openLocked(filename, Platform_OpenCreate); if (!keyfile) { error = TokenError_CantCreateFile; } else { error = saveKeys(reqs, hostname, password, keyfile); if (!platform_closeLocked(keyfile) && !error) error = TokenError_CantCreateFile; } } if (filename) free(filename); if (error && *request) free(*request); } // Free reqs while (reqs) { RSA_free(reqs->rsa); // This free's privkey too X509_REQ_free(reqs->x509); CertReq *next = reqs->next; free(reqs); reqs = next; } sk_free(x509reqs); return error; }
static LUA_FUNCTION(openssl_csr_new) { X509_REQ *csr = X509_REQ_new(); int i; int n = lua_gettop(L); int ret = X509_REQ_set_version(csr, 0L); for (i = 1; ret == 1 && i <= n; i++) { luaL_argcheck(L, auxiliar_isclass(L, "openssl.stack_of_x509_extension", i) || auxiliar_isclass(L, "openssl.stack_of_x509_attribute", i) || auxiliar_isclass(L, "openssl.x509_name", i) || auxiliar_isclass(L, "openssl.evp_pkey", i), i, "must be x509_name, stack_of_x509_extension or stack_of_x509_attribute"); if (auxiliar_isclass(L, "openssl.x509_name", i)) { X509_NAME * subject = CHECK_OBJECT(i, X509_NAME, "openssl.x509_name"); ret = X509_REQ_set_subject_name(csr, subject); } if (auxiliar_isclass(L, "openssl.stack_of_x509_attribute", i)) { int j, m; STACK_OF(X509_ATTRIBUTE) *attrs = CHECK_OBJECT(i, STACK_OF(X509_ATTRIBUTE), "openssl.stack_of_x509_attribute"); m = sk_X509_ATTRIBUTE_num(attrs); for (j = 0; ret == 1 && j < m; j++) { ret = X509_REQ_add1_attr(csr, sk_X509_ATTRIBUTE_value(attrs, j)); } } if (auxiliar_isclass(L, "openssl.stack_of_x509_extension", i)) { STACK_OF(X509_EXTENSION) *exts = CHECK_OBJECT(i, STACK_OF(X509_EXTENSION), "openssl.stack_of_x509_extension"); ret = X509_REQ_add_extensions(csr, exts); } if (auxiliar_isclass(L, "openssl.evp_pkey", i)) { EVP_PKEY *pkey; const EVP_MD *md; luaL_argcheck(L, i == n || i == n - 1, i, "must is evp_pkey object"); pkey = CHECK_OBJECT(i, EVP_PKEY, "openssl.evp_pkey"); luaL_argcheck(L, openssl_pkey_is_private(pkey), i, "must be private key"); if (i == n - 1) md = get_digest(L, n); else md = EVP_get_digestbyname("sha1"); ret = X509_REQ_set_pubkey(csr, pkey); if (ret == 1) { ret = X509_REQ_sign(csr, pkey, md); if (ret > 0) ret = 1; } break; } }; if (ret == 1) PUSH_OBJECT(csr, "openssl.x509_req"); else { X509_REQ_free(csr); return openssl_pushresult(L, ret); } return 1; }
int openssl_x509_cert() { BIO *b; FILE *fp; RSA *rsa; EVP_PKEY *pkey; X509_NAME *name; const EVP_MD *md; X509_REQ *req, **req2; X509_NAME_ENTRY *entry; unsigned int len; char bytes[COMM_LEN]; const unsigned char *pp; unsigned char *p, *der, *mdout, buf[MAX1_LEN]; OpenSSL_add_all_algorithms(); printf("\nX509_Cert info:\n"); return -1; req = X509_REQ_new(); X509_REQ_set_version(req, 1); name = X509_NAME_new(); strcpy(bytes, "beike"); entry = X509_NAME_ENTRY_create_by_txt(&entry, "commonName", V_ASN1_UTF8STRING, (unsigned char *)bytes, strlen(bytes)); X509_NAME_add_entry(name, entry, 0, -1); strcpy(bytes, "BEIJING"); entry = X509_NAME_ENTRY_create_by_txt(&entry, "countryName", V_ASN1_UTF8STRING, (unsigned char *)bytes, strlen(bytes)); X509_NAME_add_entry(name, entry, 1, -1); X509_REQ_set_subject_name(req, name); pkey = EVP_PKEY_new(); rsa = RSA_generate_key(LINE_LEN, RSA_3, NULL, NULL); EVP_PKEY_assign_RSA(pkey, rsa); X509_REQ_set_pubkey(req, pkey); strcpy(bytes, "USTB"); X509_REQ_add1_attr_by_txt(req, "organizationName", V_ASN1_UTF8STRING, (unsigned char *)bytes, strlen(bytes)); strcpy(bytes, "TECH"); X509_REQ_add1_attr_by_txt(req, "organizationalUnitName", V_ASN1_UTF8STRING, (unsigned char *)bytes, strlen(bytes)); md = EVP_sha1(); X509_REQ_digest(req, md, mdout, &len); X509_REQ_sign(req, pkey, md); b = BIO_new_file("/tmp/certreq.txt", "w"); PEM_write_bio_X509_REQ(b, req); BIO_free(b); len = i2d_X509_REQ(req, NULL); der = (unsigned char *)malloc(len); p = der; len = i2d_X509_REQ(req, &p); X509_REQ_verify(req, pkey); fp = fopen("/tmp/certder.txt", "wb"); fwrite(der, 1, len, fp); fclose(fp); free(der); X509_REQ_free(req); b = BIO_new_file("/tmp/certreq.txt", "r"); PEM_read_bio_X509_REQ(b, NULL, NULL, NULL); fp = fopen("/tmp/certder.txt", "r"); len = fread(buf, 1, MAX1_LEN, fp); fclose(fp); pp = buf; req2 = (X509_REQ **) malloc(sizeof(X509_REQ *)); d2i_X509_REQ(req2, &pp, len); free(req2); X509_REQ_free(*req2); return 0; }
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 }
void LFNetConfigLoader::retrieveConfig() { this->notifyStatus("Loading OpenSSL stuff ..."); OpenSSL_add_all_algorithms(); ERR_load_BIO_strings(); ERR_load_crypto_strings(); this->notifyStatus("Generating private key ..."); BIGNUM* e = BN_new(); BN_set_word(e, RSA_F4); RSA* key = RSA_new(); RSA_generate_key_ex(key, 4096, e, NULL); this->notifyStatus("Saving private key ..."); BIO* privateKey = BIO_new_file((_configLocation + "/private.key").toLocal8Bit().data(), "w"); PEM_write_bio_RSAPrivateKey(privateKey, key, NULL, NULL, 0, NULL, NULL); BIO_free(privateKey); this->notifyStatus("Generating csr ..."); EVP_PKEY* pkey = EVP_PKEY_new(); EVP_PKEY_assign_RSA(pkey, key); X509_NAME* name = X509_NAME_new(); X509_NAME_add_entry_by_txt(name, "O", MBSTRING_UTF8, (unsigned char*)"LF-Net", -1, -1, 0); X509_NAME_add_entry_by_txt(name, "OU", MBSTRING_UTF8, (unsigned char*)"VPN", -1, -1, 0); X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_UTF8, (unsigned char*)(_username.toUpper() + "_" + _computerName.toUpper()).toUtf8().data(), -1, -1, 0); X509_REQ* req = X509_REQ_new(); X509_REQ_set_pubkey(req, pkey); X509_REQ_set_subject_name(req, name); X509_REQ_set_version(req, 1); X509_REQ_sign(req, pkey, EVP_sha512()); BIO* request = BIO_new(BIO_s_mem()); PEM_write_bio_X509_REQ(request, req); BUF_MEM* requestData; BIO_get_mem_ptr(request, &requestData); this->notifyStatus("Request certificate using generated csr ..."); QNetworkAccessManager *mgr = new QNetworkAccessManager(this); connect(mgr, SIGNAL(finished(QNetworkReply*)), this, SLOT(certificateRequestFinished(QNetworkReply*))); connect(mgr, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), this, SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*))); QNetworkRequest netRequest(QUrl("https://mokoscha.lf-net.org/request_certificate")); netRequest.setHeader(QNetworkRequest::ContentTypeHeader, "text/plain"); mgr->post(netRequest, QByteArray(requestData->data, requestData->length)); this->notifyStatus("Cleaning up temporary data ..."); BIO_free(request); X509_REQ_free(req); X509_NAME_free(name); EVP_PKEY_free(pkey); BN_free(e); this->notifyStatus("Waiting for certificate ..."); }
int createCertificateRequest(char* result, char* keyToCertify, char * country, char* state, char* loc, char* organisation, char *organisationUnit, char* cname, char* email) { BIO *mem = BIO_new(BIO_s_mem()); X509_REQ *req=X509_REQ_new(); X509_NAME *nm = X509_NAME_new(); int err=0; //fill in details if (strlen(country) > 0) { if(!(err = X509_NAME_add_entry_by_txt(nm,"C", MBSTRING_UTF8, (unsigned char*)country, -1, -1, 0))) { return err; } } if (strlen(state) > 0) { if(!(err = X509_NAME_add_entry_by_txt(nm,"ST", MBSTRING_UTF8, (unsigned char*)state, -1, -1, 0))) { return err; } } if (strlen(loc) > 0) { if(!(err = X509_NAME_add_entry_by_txt(nm,"L", MBSTRING_UTF8, (unsigned char*)loc, -1, -1, 0))) { return err; } } if (strlen(organisation) > 0) { if(!(err = X509_NAME_add_entry_by_txt(nm,"O", MBSTRING_UTF8, (unsigned char*)organisation, -1, -1, 0))) { return err; } } if (strlen(organisationUnit) > 0) { if(!(err = X509_NAME_add_entry_by_txt(nm,"OU", MBSTRING_UTF8, (unsigned char*)organisationUnit, -1, -1, 0))) { return err; } } // This is mandatory to have, rest are optional if(!(err = X509_NAME_add_entry_by_txt(nm,"CN", MBSTRING_UTF8, (unsigned char*) cname, -1, -1, 0))) { return err; } if (strlen(email) > 0) { if(!(err = X509_NAME_add_entry_by_txt(nm,"emailAddress",MBSTRING_UTF8, (unsigned char*)email, -1, -1, 0))) { return err; } } if(!(err = X509_REQ_set_subject_name(req, nm))) { return err; } //Set the public key //...convert PEM private key into a BIO BIO* bmem = BIO_new_mem_buf(keyToCertify, -1); if (!bmem) { BIO_free(bmem); return -3; } // read the private key into an EVP_PKEY structure EVP_PKEY* privkey = PEM_read_bio_PrivateKey(bmem, NULL, NULL, NULL); if (!privkey) { BIO_free(bmem); return -4; } if(!(err = X509_REQ_set_pubkey(req, privkey))) { BIO_free(bmem); return err; } if(!(err = X509_REQ_set_version(req,3))) { BIO_free(bmem); return err; } //write it to PEM format if (!(err = PEM_write_bio_X509_REQ(mem, req))) { BIO_free(mem); BIO_free(bmem); return err; } BUF_MEM *bptr; BIO_get_mem_ptr(mem, &bptr); BIO_read(mem, result, bptr->length); BIO_free(bmem); BIO_free(mem); return 0; }
inline void certificate_request::set_version(long _version) const { error::throw_error_if_not(X509_REQ_set_version(ptr().get(), _version) != 0); }