int signRequest(char* pemRequest, int days, char* pemCAKey, char* pemCaCert, int certType, char *url, char* result) { BIO* bioReq = BIO_new_mem_buf(pemRequest, -1); BIO* bioCAKey = BIO_new_mem_buf(pemCAKey, -1); BIO* bioCert = BIO_new_mem_buf(pemCaCert, -1); X509* caCert = PEM_read_bio_X509(bioCert, NULL, NULL, NULL); int err = 0; X509_REQ *req=NULL; if (!(req=PEM_read_bio_X509_REQ(bioReq, NULL, NULL, NULL))) { BIO_free(bioReq); BIO_free(bioCert); BIO_free(bioCAKey); return ERR_peek_error(); } EVP_PKEY* caKey = PEM_read_bio_PrivateKey(bioCAKey, NULL, NULL, NULL); if (!caKey) { BIO_free(bioReq); BIO_free(bioCert); BIO_free(bioCAKey); return ERR_peek_error(); } X509* cert = X509_new(); EVP_PKEY* reqPub; if(!(err = X509_set_version(cert, 2))) { BIO_free(bioReq); BIO_free(bioCAKey); return ERR_peek_error(); } //redo all the certificate details, because OpenSSL wants us to work hard X509_set_issuer_name(cert, X509_get_subject_name(caCert)); ASN1_UTCTIME *s=ASN1_UTCTIME_new(); // Jira-issue: WP-37 // This is temp solution for putting pzp validity 5 minutes before current time // If there is a small clock difference between machines, it results in cert_not_yet_valid // It does set GMT time but is relevant to machine time. // A better solution would be to have ntp server contacted to get a proper time. if(certType == 2) { X509_gmtime_adj(s, long(0-300)); } else { X509_gmtime_adj(s, long(0)); } // End of WP-37 X509_set_notBefore(cert, s); X509_gmtime_adj(s, (long)60*60*24*days); X509_set_notAfter(cert, s); ASN1_UTCTIME_free(s); X509_set_subject_name(cert, X509_REQ_get_subject_name(req)); reqPub = X509_REQ_get_pubkey(req); X509_set_pubkey(cert,reqPub); EVP_PKEY_free(reqPub); //create a serial number at random ASN1_INTEGER* serial = getRandomSN(); X509_set_serialNumber(cert, serial); X509_EXTENSION *ex; X509V3_CTX ctx; X509V3_set_ctx_nodb(&ctx); X509V3_set_ctx(&ctx, cert, cert, NULL, NULL, 0); char *str = (char*)malloc(strlen("caIssuers;") + strlen(url) + 1); if (str == NULL) { return -10; } strcpy(str, "caIssuers;"); strcat(str, url); if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_info_access, (char*)str))) { free(str); return ERR_peek_error(); } else { X509_add_ext(cert, ex, -1); } free(str); if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_subject_alt_name, (char*)url))) { return ERR_peek_error(); } else { X509_add_ext(cert, ex, -1); } if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_issuer_alt_name, (char*)"issuer:copy"))) { return ERR_peek_error(); } else { X509_add_ext(cert, ex, -1); } if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_subject_key_identifier, (char*)"hash"))) { return ERR_peek_error(); } else { X509_add_ext(cert, ex, -1); } if( certType == 1) { if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_basic_constraints, (char*)"critical, CA:FALSE"))) { return ERR_peek_error(); } else { X509_add_ext(cert, ex, -1); } if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_ext_key_usage, (char*)"critical, clientAuth, serverAuth"))) { return ERR_peek_error(); } else { X509_add_ext(cert, ex, -1); } } else if( certType == 2) { if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_basic_constraints, (char*)"critical, CA:FALSE"))) { return ERR_peek_error(); } else { X509_add_ext(cert, ex, -1); } if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_ext_key_usage, (char*)"critical, clientAuth, serverAuth"))) { return ERR_peek_error(); } else { X509_add_ext(cert, ex, -1); } } if (!(err = X509_sign(cert,caKey,EVP_sha1()))) { BIO_free(bioReq); BIO_free(bioCert); BIO_free(bioCAKey); return err; } BIO *mem = BIO_new(BIO_s_mem()); PEM_write_bio_X509(mem,cert); BUF_MEM *bptr; BIO_get_mem_ptr(mem, &bptr); BIO_read(mem, result, bptr->length); BIO_free(mem); BIO_free(bioReq); BIO_free(bioCert); BIO_free(bioCAKey); return 0; }
int selfSignRequest(char* pemRequest, int days, char* pemCAKey, int certType, char *url, char* result) { BIO* bioReq = BIO_new_mem_buf(pemRequest, -1); BIO* bioCAKey = BIO_new_mem_buf(pemCAKey, -1); int err = 0; X509_REQ *req=NULL; if (!(req=PEM_read_bio_X509_REQ(bioReq, NULL, NULL, NULL))) { BIO_free(bioReq); BIO_free(bioCAKey); return -5; } EVP_PKEY* caKey = PEM_read_bio_PrivateKey(bioCAKey, NULL, NULL, NULL); if (!caKey) { BIO_free(bioReq); BIO_free(bioCAKey); return -6; } X509* cert = X509_new(); EVP_PKEY* reqPub; //redo all the certificate details, because OpenSSL wants us to work hard if(!(err = X509_set_version(cert, 2))) { BIO_free(bioReq); BIO_free(bioCAKey); return err; } if(!(err = X509_set_issuer_name(cert, X509_REQ_get_subject_name(req)))) { BIO_free(bioReq); BIO_free(bioCAKey); return err; } ASN1_UTCTIME *s=ASN1_UTCTIME_new(); // Jira-issue: WP-37 // This is temp solution for putting pzp validity 5 minutes before current time // If there is a small clock difference between machines, it results in cert_not_yet_valid // It does set GMT time but is relevant to machine time. // A better solution would be to have ntp server contacted to get proper time. if(certType == 2) { X509_gmtime_adj(s, long(0-300)); } else { X509_gmtime_adj(s, long(0)); } // End of WP-37 X509_set_notBefore(cert, s); X509_gmtime_adj(s, (long)60*60*24*days); X509_set_notAfter(cert, s); ASN1_UTCTIME_free(s); if(!(err = X509_set_subject_name(cert, X509_REQ_get_subject_name(req)))) { BIO_free(bioReq); BIO_free(bioCAKey); return err; } if (!(reqPub = X509_REQ_get_pubkey(req))) { BIO_free(bioReq); BIO_free(bioCAKey); return -7; } err = X509_set_pubkey(cert,reqPub); EVP_PKEY_free(reqPub); if (!err) { return err; // an error occurred, this is terrible style. } //create a serial number at random ASN1_INTEGER* serial = getRandomSN(); X509_set_serialNumber(cert, serial); // V3 extensions X509_EXTENSION *ex; X509V3_CTX ctx; X509V3_set_ctx_nodb(&ctx); X509V3_set_ctx(&ctx, cert, cert, NULL, NULL, 0); if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_subject_alt_name, (char*)url))) { return ERR_peek_error(); } else { X509_add_ext(cert, ex, -1); } if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_subject_key_identifier, (char*)"hash"))) { return ERR_peek_error(); } else { X509_add_ext(cert, ex, -1); } if( certType == 0) { if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_basic_constraints, (char*)"critical, CA:TRUE"))) { return ERR_peek_error(); } else { X509_add_ext(cert, ex, -1); } if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_key_usage, (char*)"critical, keyCertSign, digitalSignature, cRLSign"))) { /* critical, keyCertSign,cRLSign, nonRepudiation,*/ return ERR_peek_error(); } else { X509_add_ext(cert, ex, -1); } if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_ext_key_usage, (char*)"critical, serverAuth"))) { return ERR_peek_error(); } else { X509_add_ext(cert, ex, -1); } if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_inhibit_any_policy, (char*)"0"))) { return ERR_peek_error(); } else { X509_add_ext(cert, ex, -1); } if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_crl_distribution_points, (char*)url))) { return ERR_peek_error(); } else { X509_add_ext(cert, ex, -1); } } if (!(err = X509_sign(cert,caKey,EVP_sha1()))) { BIO_free(bioReq); BIO_free(bioCAKey); return err; } BIO *mem = BIO_new(BIO_s_mem()); PEM_write_bio_X509(mem,cert); BUF_MEM *bptr; BIO_get_mem_ptr(mem, &bptr); BIO_read(mem, result, bptr->length); BIO_free(mem); BIO_free(bioReq); BIO_free(bioCAKey); return 0; }
void AuthorityCertificateManager::getCertificateForTarget(boost::asio::ip::tcp::endpoint &endpoint, bool wildcardOK, X509 *serverCertificate, Certificate **cert, std::list<Certificate*> **chainList) { X509_NAME *serverName = X509_get_subject_name(serverCertificate); X509_NAME *issuerName = X509_get_subject_name(authority->getCert()); X509 *request = X509_new(); X509_set_version(request, 3); X509_set_subject_name(request, serverName); X509_set_issuer_name(request, issuerName); ASN1_INTEGER_set(X509_get_serialNumber(request), generateRandomSerial()); X509_gmtime_adj(X509_get_notBefore(request), -365); X509_gmtime_adj(X509_get_notAfter(request), (long)60*60*24*365); X509_set_pubkey(request, this->leafPair); X509_sign(request, authority->getKey(), EVP_sha1()); Certificate *leaf = new Certificate(); leaf->setCert(request); leaf->setKey(this->leafPair); *cert = leaf; *chainList = &(this->chainList); // *chain = this->authority; }
static X509 * GenerateX509Cert(X509_REQ *req, // IN CONF *config, // IN int days) // IN { X509 *cert; X509V3_CTX ctx; char *extensions; gboolean ret = FALSE; gchar *err = NULL; cert = X509_new(); if (!cert) { Error("Failed to allocate a X509 certificate: %s.\n", GetSSLError(&err)); goto exit; } if (!SetCertSerialNumber(cert)) { goto exit; } if (!X509_set_issuer_name(cert, X509_REQ_get_subject_name(req)) || !X509_gmtime_adj(X509_get_notBefore(cert), 0) || !X509_gmtime_adj(X509_get_notAfter(cert), (long)60*60*24*days) || !X509_set_subject_name(cert, X509_REQ_get_subject_name(req))) { Error("Failed to configure the X509 certificate: %s.\n", GetSSLError(&err)); goto exit; } X509V3_set_ctx(&ctx, cert, cert, NULL, NULL, 0); X509V3_set_nconf(&ctx, config); extensions = NCONF_get_string(config, "req", "x509_extensions"); if (extensions) { if (!X509_set_version(cert, 2)) { Error("Failed to set the certificate version: %s.\n", GetSSLError(&err)); goto exit; } if (!X509V3_EXT_add_nconf(config, &ctx, extensions, cert)) { Error("Error loading extension section %s: %s.\n", extensions, GetSSLError(&err)); goto exit; } } ret = TRUE; exit: if (!ret) { X509_free(cert); cert = NULL; } g_free(err); return cert; }
static int set_cn(X509 *crt, ...) { int ret = 0; X509_NAME *n = NULL; va_list ap; va_start(ap, crt); n = X509_NAME_new(); if (n == NULL) goto out; while (1) { int nid; const char *name; nid = va_arg(ap, int); if (nid == 0) break; name = va_arg(ap, const char *); if (!X509_NAME_add_entry_by_NID(n, nid, MBSTRING_ASC, (unsigned char *)name, -1, -1, 1)) goto out; } if (!X509_set_subject_name(crt, n)) goto out; ret = 1; out: X509_NAME_free(n); va_end(ap); return ret; }
/* creates a self-signed certificate for a key */ X509 * ship_create_selfsigned_cert(char *subject, int ttl, RSA* signer_key) { X509 *x = 0, *ret = 0; X509_NAME *tmp = 0; EVP_PKEY *pr_key = 0; ASSERT_TRUE(x = X509_new(), err); ASSERT_TRUE(pr_key = EVP_PKEY_new(), err); ASSERT_TRUE(EVP_PKEY_set1_RSA(pr_key, signer_key), err); ASSERT_TRUE(X509_set_version(x, 2), err); /* version 3 certificate */ ASN1_INTEGER_set(X509_get_serialNumber(x), 0); ASSERT_TRUE(X509_gmtime_adj(X509_get_notBefore(x), 0), err); ASSERT_TRUE(X509_gmtime_adj(X509_get_notAfter(x), (long)ttl), err); ASSERT_TRUE(tmp = X509_get_subject_name(x), err); ASSERT_TRUE(X509_NAME_add_entry_by_txt(tmp, "CN", MBSTRING_ASC, (unsigned char*)subject, -1, -1, 0), err); ASSERT_TRUE(X509_set_subject_name(x, tmp), err); ASSERT_TRUE(X509_set_pubkey(x, pr_key), err); ASSERT_TRUE(X509_sign(x, pr_key, EVP_sha1()), err); ret = x; x = NULL; err: if (x) X509_free(x); if (pr_key) EVP_PKEY_free(pr_key); return ret; }
Certificate::Certificate(const string& _subject, const string& _issuer, const string& _validity, const Node::Id_t _owner, RSA *_rsaPubKey) : #ifdef DEBUG_LEAKS LeakMonitor(LEAK_TYPE_CERTIFICATE), #endif stored(false), verified(false), hasSignature(false), x(NULL), subject(_subject), issuer(_issuer), validity(_validity), pubKey(NULL), rsaPubKey(NULL), x509_PEM_str(NULL) { memcpy(owner, _owner, sizeof(Node::Id_t)); x = X509_new(); if (!x) { HAGGLE_ERR("Could not allocate X509 certificate struct\n"); return; } X509_set_version(x, 2); pubKey = EVP_PKEY_new(); if (!pubKey) { X509_free(x); HAGGLE_ERR("Could not allocate X509 EVP_PKEY\n"); return; } EVP_PKEY_assign_RSA(pubKey, RSAPublicKey_dup(_rsaPubKey)); X509_set_pubkey(x, pubKey); rsaPubKey = EVP_PKEY_get1_RSA(pubKey); /* Set validity. FIXME: currently hardcoded */ int days = 30; X509_gmtime_adj(X509_get_notBefore(x),0); X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days); X509_NAME *subject_name = X509_get_subject_name(x); /* Set subject */ //X509_NAME_add_entry_by_txt(subname,"C", MBSTRING_ASC, "SE", -1, -1, 0); X509_NAME_add_entry_by_txt(subject_name, "CN", MBSTRING_ASC, (const unsigned char *)subject.c_str(), -1, -1, 0); X509_NAME_add_entry_by_txt(subject_name, "O", MBSTRING_ASC, (const unsigned char *)"Haggle", -1, -1, 0); X509_set_subject_name(x, subject_name); /* Set issuer */ X509_NAME *issuer_name = X509_get_issuer_name(x); X509_NAME_add_entry_by_txt(issuer_name, "CN", MBSTRING_ASC, (const unsigned char *)issuer.c_str(), -1, -1, 0); X509_NAME_add_entry_by_txt(issuer_name, "O", MBSTRING_ASC, (const unsigned char *)"Haggle", -1, -1, 0); X509_set_issuer_name(x, issuer_name); //HAGGLE_DBG("Subject=\'%s\' issuer=\'%s\'\n", subject.c_str(), issuer.c_str()); certificate_set_serial(x); }
// Generate a self-signed certificate, with the public key from the // given key pair. Caller is responsible for freeing the returned object. static X509* MakeCertificate(EVP_PKEY* pkey, const char* common_name) { LOG(LS_INFO) << "Making certificate for " << common_name; X509* x509 = NULL; BIGNUM* serial_number = NULL; X509_NAME* name = NULL; if ((x509=X509_new()) == NULL) goto error; if (!X509_set_pubkey(x509, pkey)) goto error; // serial number // temporary reference to serial number inside x509 struct ASN1_INTEGER* asn1_serial_number; if (!(serial_number = BN_new()) || !BN_pseudo_rand(serial_number, SERIAL_RAND_BITS, 0, 0) || !(asn1_serial_number = X509_get_serialNumber(x509)) || !BN_to_ASN1_INTEGER(serial_number, asn1_serial_number)) goto error; if (!X509_set_version(x509, 0L)) // version 1 goto error; // There are a lot of possible components for the name entries. In // our P2P SSL mode however, the certificates are pre-exchanged // (through the secure XMPP channel), and so the certificate // identification is arbitrary. It can't be empty, so we set some // arbitrary common_name. Note that this certificate goes out in // clear during SSL negotiation, so there may be a privacy issue in // putting anything recognizable here. if (!(name = X509_NAME_new()) || !X509_NAME_add_entry_by_NID(name, NID_commonName, MBSTRING_UTF8, (unsigned char*)common_name, -1, -1, 0) || !X509_set_subject_name(x509, name) || !X509_set_issuer_name(x509, name)) goto error; if (!X509_gmtime_adj(X509_get_notBefore(x509), 0) || !X509_gmtime_adj(X509_get_notAfter(x509), CERTIFICATE_LIFETIME)) goto error; if (!X509_sign(x509, pkey, EVP_sha1())) goto error; BN_free(serial_number); X509_NAME_free(name); LOG(LS_INFO) << "Returning certificate"; return x509; error: BN_free(serial_number); X509_NAME_free(name); X509_free(x509); return NULL; }
static X509 *X509_REQ_to_X509_ex(X509_REQ *r, int days, EVP_PKEY *pkey, const EVP_MD* md) { X509 *ret = NULL; X509_CINF *xi = NULL; X509_NAME *xn; EVP_PKEY *pubkey = NULL; int res; if ((ret = X509_new()) == NULL) { X509err(X509_F_X509_REQ_TO_X509, ERR_R_MALLOC_FAILURE); return NULL; } /* duplicate the request */ xi = ret->cert_info; if (sk_X509_ATTRIBUTE_num(r->req_info->attributes) != 0) { if ((xi->version = M_ASN1_INTEGER_new()) == NULL) goto err; if (!ASN1_INTEGER_set(xi->version, 2)) goto err; /*- xi->extensions=ri->attributes; <- bad, should not ever be done ri->attributes=NULL; */ } xn = X509_REQ_get_subject_name(r); if (X509_set_subject_name(ret, xn) == 0) goto err; if (X509_set_issuer_name(ret, xn) == 0) goto err; if (X509_gmtime_adj(xi->validity->notBefore, 0) == NULL) goto err; if (X509_gmtime_adj(xi->validity->notAfter, (long)60 * 60 * 24 * days) == NULL) goto err; pubkey = X509_REQ_get_pubkey(r); res = X509_set_pubkey(ret, pubkey); EVP_PKEY_free(pubkey); if (!md) goto err; if (!res || !X509_sign(ret, pkey, md)) goto err; if (0) { err: X509_free(ret); ret = NULL; } return (ret); }
X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey) { X509 *ret = NULL; X509_CINF *xi = NULL; X509_NAME *xn; if ((ret = X509_new()) == NULL) { OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); goto err; } /* duplicate the request */ xi = ret->cert_info; if (sk_X509_ATTRIBUTE_num(r->req_info->attributes) != 0) { if ((xi->version = M_ASN1_INTEGER_new()) == NULL) goto err; if (!ASN1_INTEGER_set(xi->version, 2)) goto err; /* * xi->extensions=ri->attributes; <- bad, should not ever be done * ri->attributes=NULL; */ } xn = X509_REQ_get_subject_name(r); if (X509_set_subject_name(ret, X509_NAME_dup(xn)) == 0) goto err; if (X509_set_issuer_name(ret, X509_NAME_dup(xn)) == 0) goto err; if (X509_gmtime_adj(xi->validity->notBefore, 0) == NULL) goto err; if (X509_gmtime_adj(xi->validity->notAfter, (long)60 * 60 * 24 * days) == NULL) goto err; X509_set_pubkey(ret, X509_REQ_get_pubkey(r)); if (!X509_sign(ret, pkey, EVP_md5())) goto err; if (0) { err: X509_free(ret); ret = NULL; } return (ret); }
static X509 *pki_certificate(X509_NAME *issuer, EVP_PKEY *keyring, X509_REQ *cert_req, uint8_t is_cert_authority, uint32_t serial, uint32_t expiration_delay) { jlog(L_DEBUG, "pki_certificate"); X509 *certificate; X509_NAME *subject; X509V3_CTX ctx; X509_EXTENSION *ext; // create a new certificate certificate = X509_new(); // set certificate unique serial number ASN1_INTEGER_set(X509_get_serialNumber(certificate), serial); // set certificate 'Subject:' subject = X509_REQ_get_subject_name(cert_req); X509_set_subject_name(certificate, subject); // set certificate 'Issuer:' X509_set_issuer_name(certificate, issuer); // set X509v3 extension "basicConstraints" CA:TRUE/FALSE X509V3_set_ctx(&ctx, NULL, certificate, cert_req, NULL, 0); if (is_cert_authority == true) ext = X509V3_EXT_conf(NULL, &ctx, "basicConstraints", "CA:TRUE"); else ext = X509V3_EXT_conf(NULL, &ctx, "basicConstraints", "CA:FALSE"); X509_add_ext(certificate, ext, -1); X509_EXTENSION_free(ext); // set certificate version 3 X509_set_version(certificate, 0x2); // set certificate public key X509_set_pubkey(certificate, keyring); // set the 'notBefore' to yersterday X509_gmtime_adj(X509_get_notBefore(certificate), -(24*60*60)); // set certificate expiration delay X509_gmtime_adj(X509_get_notAfter(certificate), expiration_delay); return certificate; }
static X509 * gen_cert(EVP_PKEY* pkey, const char *common, int days) { X509 *x509 = NULL; BIGNUM *serial_number = NULL; X509_NAME *name = NULL; if ((x509 = X509_new()) == NULL) return NULL; if (!X509_set_pubkey(x509, pkey)) return NULL; ASN1_INTEGER* asn1_serial_number; if ((serial_number = BN_new()) == NULL || !BN_pseudo_rand(serial_number, 64, 0, 0) || (asn1_serial_number = X509_get_serialNumber(x509)) == NULL || !BN_to_ASN1_INTEGER(serial_number, asn1_serial_number)) goto cert_err; if (!X509_set_version(x509, 0L)) // version 1 goto cert_err; if ((name = X509_NAME_new()) == NULL || !X509_NAME_add_entry_by_NID( name, NID_commonName, MBSTRING_UTF8, (unsigned char*)common, -1, -1, 0) || !X509_set_subject_name(x509, name) || !X509_set_issuer_name(x509, name)) goto cert_err; if (!X509_gmtime_adj(X509_get_notBefore(x509), 0) || !X509_gmtime_adj(X509_get_notAfter(x509), days * 24 * 3600)) goto cert_err; if (!X509_sign(x509, pkey, EVP_sha1())) goto cert_err; if (0) { cert_err: X509_free(x509); x509 = NULL; } BN_free(serial_number); X509_NAME_free(name); return x509; }
void mkcert(X509_REQ* req, const char* rootkey, const char* rootcert, const char* passwd) { RSA* rsa_key = EVP_PKEY_get1_RSA(X509_PUBKEY_get(req->req_info->pubkey)); int key_length = RSA_size(rsa_key); if (key_len != 128) { fprintf(stderr, "CA::key length of req is %d, not long enough\n"); return NULL; } X509* cacert = X509_new(); assert(cacert != NULL); load_cacert(&cacert, rootcert); EVP_PKEY* cakey = EVP_PKEY_new(); load_cakey(&cakey, rootkey, passwd); PEM_write_PrivateKey(stdout, cakey, NULL, NULL, 0, NULL, NULL); PEM_write_PUBKEY(stdout, cakey); X509* x = X509_new(); X509_set_version(x, 3); ASN1_INTEGER_set(X509_get_serialNumber(x), 1024); X509_gmtime_adj(X509_get_notBefore(x), 0); X509_gmtime_adj(X509_get_notAfter(x), (long)60 * 60 * 24 * 365); X509_set_pubkey(x, X509_PUBKEY_get(req->req_info->pubkey)); X509_set_subject_name(x, X509_REQ_get_subject_name(req)); X509_set_issuer_name(x, X509_get_subject_name(cacert)); assert(X509_sign(x, cakey, EVP_sha1()) > 0); FILE* f = fopen("usercert.pem", "wb"); PEM_write_X509(f, x); fclose(f); X509_print_fp(stdout, x); PEM_write_X509(stdout, x); X509_free(cacert); EVP_PKEY_free(cakey); }
static X509 * getcert(void) { /* Dummy code to make a quick-and-dirty valid certificate with OpenSSL. Don't copy this code into your own program! It does a number of things in a stupid and insecure way. */ X509 *x509 = NULL; X509_NAME *name = NULL; EVP_PKEY *key = getkey(); int nid; time_t now = time(NULL); tt_assert(key); x509 = X509_new(); tt_assert(x509); tt_assert(0 != X509_set_version(x509, 2)); tt_assert(0 != ASN1_INTEGER_set(X509_get_serialNumber(x509), (long)now)); name = X509_NAME_new(); tt_assert(name); nid = OBJ_txt2nid("commonName"); tt_assert(NID_undef != nid); tt_assert(0 != X509_NAME_add_entry_by_NID( name, nid, MBSTRING_ASC, (unsigned char*)"example.com", -1, -1, 0)); X509_set_subject_name(x509, name); X509_set_issuer_name(x509, name); X509_time_adj(X509_get_notBefore(x509), 0, &now); now += 3600; X509_time_adj(X509_get_notAfter(x509), 0, &now); X509_set_pubkey(x509, key); tt_assert(0 != X509_sign(x509, key, EVP_sha1())); return x509; end: X509_free(x509); return NULL; }
sqbind::SQINT COsslCert::SetNameField( const sqbind::stdString &sField, const sqbind::stdString &sValue ) {_STT(); if ( !m_pX509 ) return 0; if ( !sField.length() ) return 0; // Get name object X509_NAME *pName = X509_get_subject_name( m_pX509 ); if ( !pName ) return 0; // Set specified field X509_NAME_add_entry_by_txt( pName, sField.c_str(), MBSTRING_ASC, (const unsigned char *)sValue.c_str(), -1, -1, 0 ); // Set issuer name to be the same X509_set_subject_name( m_pX509, pName ); X509_set_issuer_name( m_pX509, pName ); return 1; }
/* * 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())); } }
int x509_main(int argc, char **argv) { ASN1_INTEGER *sno = NULL; ASN1_OBJECT *objtmp; BIO *out = NULL; CONF *extconf = NULL; EVP_PKEY *Upkey = NULL, *CApkey = NULL, *fkey = NULL; STACK_OF(ASN1_OBJECT) *trust = NULL, *reject = NULL; STACK_OF(OPENSSL_STRING) *sigopts = NULL; X509 *x = NULL, *xca = NULL; X509_REQ *req = NULL, *rq = NULL; X509_STORE *ctx = NULL; const EVP_MD *digest = NULL; char *CAkeyfile = NULL, *CAserial = NULL, *fkeyfile = NULL, *alias = NULL; char *checkhost = NULL, *checkemail = NULL, *checkip = NULL; char *extsect = NULL, *extfile = NULL, *passin = NULL, *passinarg = NULL; char *infile = NULL, *outfile = NULL, *keyfile = NULL, *CAfile = NULL; char buf[256], *prog; int x509req = 0, days = DEF_DAYS, modulus = 0, pubkey = 0, pprint = 0; int C = 0, CAformat = FORMAT_PEM, CAkeyformat = FORMAT_PEM; int fingerprint = 0, reqfile = 0, need_rand = 0, checkend = 0; int informat = FORMAT_PEM, outformat = FORMAT_PEM, keyformat = FORMAT_PEM; int next_serial = 0, subject_hash = 0, issuer_hash = 0, ocspid = 0; int noout = 0, sign_flag = 0, CA_flag = 0, CA_createserial = 0, email = 0; int ocsp_uri = 0, trustout = 0, clrtrust = 0, clrreject = 0, aliasout = 0; int ret = 1, i, num = 0, badsig = 0, clrext = 0, nocert = 0; int text = 0, serial = 0, subject = 0, issuer = 0, startdate = 0; int checkoffset = 0, enddate = 0; unsigned long nmflag = 0, certflag = 0; OPTION_CHOICE o; ENGINE *e = NULL; #ifndef OPENSSL_NO_MD5 int subject_hash_old = 0, issuer_hash_old = 0; #endif ctx = X509_STORE_new(); if (ctx == NULL) goto end; X509_STORE_set_verify_cb(ctx, callb); prog = opt_init(argc, argv, x509_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(x509_options); ret = 0; goto end; case OPT_INFORM: if (!opt_format(opt_arg(), OPT_FMT_ANY, &informat)) goto opthelp; break; case OPT_IN: infile = opt_arg(); break; case OPT_OUTFORM: if (!opt_format(opt_arg(), OPT_FMT_ANY, &outformat)) goto opthelp; break; case OPT_KEYFORM: if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &keyformat)) goto opthelp; break; case OPT_CAFORM: if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &CAformat)) goto opthelp; break; case OPT_CAKEYFORM: if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &CAkeyformat)) goto opthelp; break; case OPT_OUT: outfile = opt_arg(); break; case OPT_REQ: reqfile = need_rand = 1; break; case OPT_SIGOPT: if (!sigopts) sigopts = sk_OPENSSL_STRING_new_null(); if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, opt_arg())) goto opthelp; break; #ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL case OPT_FORCE_VERSION: force_version = atoi(opt_arg()) - 1; break; #endif case OPT_DAYS: days = atoi(opt_arg()); break; case OPT_PASSIN: passinarg = opt_arg(); break; case OPT_EXTFILE: extfile = opt_arg(); break; case OPT_EXTENSIONS: extsect = opt_arg(); break; case OPT_SIGNKEY: keyfile = opt_arg(); sign_flag = ++num; need_rand = 1; break; case OPT_CA: CAfile = opt_arg(); CA_flag = ++num; need_rand = 1; break; case OPT_CAKEY: CAkeyfile = opt_arg(); break; case OPT_CASERIAL: CAserial = opt_arg(); break; case OPT_SET_SERIAL: if ((sno = s2i_ASN1_INTEGER(NULL, opt_arg())) == NULL) goto opthelp; break; case OPT_FORCE_PUBKEY: fkeyfile = opt_arg(); break; case OPT_ADDTRUST: if ((objtmp = OBJ_txt2obj(opt_arg(), 0)) == NULL) { BIO_printf(bio_err, "%s: Invalid trust object value %s\n", prog, opt_arg()); goto opthelp; } if (trust == NULL && (trust = sk_ASN1_OBJECT_new_null()) == NULL) goto end; sk_ASN1_OBJECT_push(trust, objtmp); trustout = 1; break; case OPT_ADDREJECT: if ((objtmp = OBJ_txt2obj(opt_arg(), 0)) == NULL) { BIO_printf(bio_err, "%s: Invalid reject object value %s\n", prog, opt_arg()); goto opthelp; } if (reject == NULL && (reject = sk_ASN1_OBJECT_new_null()) == NULL) goto end; sk_ASN1_OBJECT_push(reject, objtmp); trustout = 1; break; case OPT_SETALIAS: alias = opt_arg(); trustout = 1; break; case OPT_CERTOPT: if (!set_cert_ex(&certflag, opt_arg())) goto opthelp; break; case OPT_NAMEOPT: if (!set_name_ex(&nmflag, opt_arg())) goto opthelp; break; case OPT_ENGINE: e = setup_engine(opt_arg(), 0); break; case OPT_C: C = ++num; break; case OPT_EMAIL: email = ++num; break; case OPT_OCSP_URI: ocsp_uri = ++num; break; case OPT_SERIAL: serial = ++num; break; case OPT_NEXT_SERIAL: next_serial = ++num; break; case OPT_MODULUS: modulus = ++num; break; case OPT_PUBKEY: pubkey = ++num; break; case OPT_X509TOREQ: x509req = ++num; break; case OPT_TEXT: text = ++num; break; case OPT_SUBJECT: subject = ++num; break; case OPT_ISSUER: issuer = ++num; break; case OPT_FINGERPRINT: fingerprint = ++num; break; case OPT_HASH: subject_hash = ++num; break; case OPT_ISSUER_HASH: issuer_hash = ++num; break; case OPT_PURPOSE: pprint = ++num; break; case OPT_STARTDATE: startdate = ++num; break; case OPT_ENDDATE: enddate = ++num; break; case OPT_NOOUT: noout = ++num; break; case OPT_NOCERT: nocert = 1; break; case OPT_TRUSTOUT: trustout = 1; break; case OPT_CLRTRUST: clrtrust = ++num; break; case OPT_CLRREJECT: clrreject = ++num; break; case OPT_ALIAS: aliasout = ++num; break; case OPT_CACREATESERIAL: CA_createserial = ++num; break; case OPT_CLREXT: clrext = 1; break; case OPT_OCSPID: ocspid = ++num; break; case OPT_BADSIG: badsig = 1; break; #ifndef OPENSSL_NO_MD5 case OPT_SUBJECT_HASH_OLD: subject_hash_old = ++num; break; case OPT_ISSUER_HASH_OLD: issuer_hash_old = ++num; break; #endif case OPT_DATES: startdate = ++num; enddate = ++num; break; case OPT_CHECKEND: checkoffset = atoi(opt_arg()); checkend = 1; break; case OPT_CHECKHOST: checkhost = opt_arg(); break; case OPT_CHECKEMAIL: checkemail = opt_arg(); break; case OPT_CHECKIP: checkip = opt_arg(); break; case OPT_MD: if (!opt_md(opt_unknown(), &digest)) goto opthelp; } } argc = opt_num_rest(); argv = opt_rest(); if (argc != 0) { BIO_printf(bio_err, "%s: Unknown parameter %s\n", prog, argv[0]); goto opthelp; } out = bio_open_default(outfile, "w"); if (out == NULL) goto end; if (need_rand) app_RAND_load_file(NULL, 0); if (!app_passwd(passinarg, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } if (!X509_STORE_set_default_paths(ctx)) { ERR_print_errors(bio_err); goto end; } if (fkeyfile) { fkey = load_pubkey(fkeyfile, keyformat, 0, NULL, e, "Forced key"); if (fkey == NULL) goto end; } if ((CAkeyfile == NULL) && (CA_flag) && (CAformat == FORMAT_PEM)) { CAkeyfile = CAfile; } else if ((CA_flag) && (CAkeyfile == NULL)) { BIO_printf(bio_err, "need to specify a CAkey if using the CA command\n"); goto end; } if (extfile) { long errorline = -1; X509V3_CTX ctx2; extconf = NCONF_new(NULL); if (!NCONF_load(extconf, extfile, &errorline)) { if (errorline <= 0) BIO_printf(bio_err, "error loading the config file '%s'\n", extfile); else BIO_printf(bio_err, "error on line %ld of config file '%s'\n", errorline, extfile); goto end; } if (!extsect) { extsect = NCONF_get_string(extconf, "default", "extensions"); if (!extsect) { ERR_clear_error(); extsect = "default"; } } X509V3_set_ctx_test(&ctx2); X509V3_set_nconf(&ctx2, extconf); if (!X509V3_EXT_add_nconf(extconf, &ctx2, extsect, NULL)) { BIO_printf(bio_err, "Error Loading extension section %s\n", extsect); ERR_print_errors(bio_err); goto end; } } if (reqfile) { EVP_PKEY *pkey; BIO *in; if (!sign_flag && !CA_flag) { BIO_printf(bio_err, "We need a private key to sign with\n"); goto end; } in = bio_open_default(infile, "r"); if (in == NULL) goto end; req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL); BIO_free(in); if (req == NULL) { ERR_print_errors(bio_err); goto end; } if ((req->req_info == NULL) || (req->req_info->pubkey == NULL) || (req->req_info->pubkey->public_key == NULL) || (req->req_info->pubkey->public_key->data == NULL)) { BIO_printf(bio_err, "The certificate request appears to corrupted\n"); BIO_printf(bio_err, "It does not contain a public key\n"); goto end; } if ((pkey = X509_REQ_get_pubkey(req)) == NULL) { BIO_printf(bio_err, "error unpacking public key\n"); goto end; } i = X509_REQ_verify(req, pkey); EVP_PKEY_free(pkey); if (i < 0) { BIO_printf(bio_err, "Signature verification error\n"); ERR_print_errors(bio_err); goto end; } if (i == 0) { BIO_printf(bio_err, "Signature did not match the certificate request\n"); goto end; } else BIO_printf(bio_err, "Signature ok\n"); print_name(bio_err, "subject=", X509_REQ_get_subject_name(req), nmflag); if ((x = X509_new()) == NULL) goto end; if (sno == NULL) { sno = ASN1_INTEGER_new(); if (!sno || !rand_serial(NULL, sno)) goto end; if (!X509_set_serialNumber(x, sno)) goto end; ASN1_INTEGER_free(sno); sno = NULL; } else if (!X509_set_serialNumber(x, sno)) goto end; if (!X509_set_issuer_name(x, req->req_info->subject)) goto end; if (!X509_set_subject_name(x, req->req_info->subject)) goto end; X509_gmtime_adj(X509_get_notBefore(x), 0); X509_time_adj_ex(X509_get_notAfter(x), days, 0, NULL); if (fkey) X509_set_pubkey(x, fkey); else { pkey = X509_REQ_get_pubkey(req); X509_set_pubkey(x, pkey); EVP_PKEY_free(pkey); } } else x = load_cert(infile, informat, NULL, e, "Certificate"); if (x == NULL) goto end; if (CA_flag) { xca = load_cert(CAfile, CAformat, NULL, e, "CA Certificate"); if (xca == NULL) goto end; } if (!noout || text || next_serial) { OBJ_create("2.99999.3", "SET.ex3", "SET x509v3 extension 3"); } if (alias) X509_alias_set1(x, (unsigned char *)alias, -1); if (clrtrust) X509_trust_clear(x); if (clrreject) X509_reject_clear(x); if (trust) { for (i = 0; i < sk_ASN1_OBJECT_num(trust); i++) { objtmp = sk_ASN1_OBJECT_value(trust, i); X509_add1_trust_object(x, objtmp); } } if (reject) { for (i = 0; i < sk_ASN1_OBJECT_num(reject); i++) { objtmp = sk_ASN1_OBJECT_value(reject, i); X509_add1_reject_object(x, objtmp); } } if (num) { for (i = 1; i <= num; i++) { if (issuer == i) { print_name(out, "issuer= ", X509_get_issuer_name(x), nmflag); } else if (subject == i) { print_name(out, "subject= ", X509_get_subject_name(x), nmflag); } else if (serial == i) { BIO_printf(out, "serial="); i2a_ASN1_INTEGER(out, X509_get_serialNumber(x)); BIO_printf(out, "\n"); } else if (next_serial == i) { BIGNUM *bnser; ASN1_INTEGER *ser; ser = X509_get_serialNumber(x); bnser = ASN1_INTEGER_to_BN(ser, NULL); if (!bnser) goto end; if (!BN_add_word(bnser, 1)) goto end; ser = BN_to_ASN1_INTEGER(bnser, NULL); if (!ser) goto end; BN_free(bnser); i2a_ASN1_INTEGER(out, ser); ASN1_INTEGER_free(ser); BIO_puts(out, "\n"); } else if ((email == i) || (ocsp_uri == i)) { int j; STACK_OF(OPENSSL_STRING) *emlst; if (email == i) emlst = X509_get1_email(x); else emlst = X509_get1_ocsp(x); for (j = 0; j < sk_OPENSSL_STRING_num(emlst); j++) BIO_printf(out, "%s\n", sk_OPENSSL_STRING_value(emlst, j)); X509_email_free(emlst); } else if (aliasout == i) { unsigned char *alstr; alstr = X509_alias_get0(x, NULL); if (alstr) BIO_printf(out, "%s\n", alstr); else BIO_puts(out, "<No Alias>\n"); } else if (subject_hash == i) { BIO_printf(out, "%08lx\n", X509_subject_name_hash(x)); } #ifndef OPENSSL_NO_MD5 else if (subject_hash_old == i) { BIO_printf(out, "%08lx\n", X509_subject_name_hash_old(x)); } #endif else if (issuer_hash == i) { BIO_printf(out, "%08lx\n", X509_issuer_name_hash(x)); } #ifndef OPENSSL_NO_MD5 else if (issuer_hash_old == i) { BIO_printf(out, "%08lx\n", X509_issuer_name_hash_old(x)); } #endif else if (pprint == i) { X509_PURPOSE *ptmp; int j; BIO_printf(out, "Certificate purposes:\n"); for (j = 0; j < X509_PURPOSE_get_count(); j++) { ptmp = X509_PURPOSE_get0(j); purpose_print(out, x, ptmp); } } else if (modulus == i) { EVP_PKEY *pkey; pkey = X509_get_pubkey(x); if (pkey == NULL) { BIO_printf(bio_err, "Modulus=unavailable\n"); ERR_print_errors(bio_err); goto end; } BIO_printf(out, "Modulus="); #ifndef OPENSSL_NO_RSA if (pkey->type == EVP_PKEY_RSA) BN_print(out, pkey->pkey.rsa->n); else #endif #ifndef OPENSSL_NO_DSA if (pkey->type == EVP_PKEY_DSA) BN_print(out, pkey->pkey.dsa->pub_key); else #endif BIO_printf(out, "Wrong Algorithm type"); BIO_printf(out, "\n"); EVP_PKEY_free(pkey); } else if (pubkey == i) { EVP_PKEY *pkey; pkey = X509_get_pubkey(x); if (pkey == NULL) { BIO_printf(bio_err, "Error getting public key\n"); ERR_print_errors(bio_err); goto end; } PEM_write_bio_PUBKEY(out, pkey); EVP_PKEY_free(pkey); } else if (C == i) { unsigned char *d; char *m; int len; X509_NAME_oneline(X509_get_subject_name(x), buf, sizeof buf); BIO_printf(out, "/*\n" " * Subject: %s\n", buf); m = X509_NAME_oneline(X509_get_issuer_name(x), buf, sizeof buf); BIO_printf(out, " * Issuer: %s\n" " */\n", buf); len = i2d_X509(x, NULL); m = app_malloc(len, "x509 name buffer"); d = (unsigned char *)m; len = i2d_X509_NAME(X509_get_subject_name(x), &d); print_array(out, "the_subject_name", len, (unsigned char *)m); d = (unsigned char *)m; len = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x), &d); print_array(out, "the_public_key", len, (unsigned char *)m); d = (unsigned char *)m; len = i2d_X509(x, &d); print_array(out, "the_certificate", len, (unsigned char *)m); OPENSSL_free(m); } else if (text == i) { X509_print_ex(out, x, nmflag, certflag); } else if (startdate == i) { BIO_puts(out, "notBefore="); ASN1_TIME_print(out, X509_get_notBefore(x)); BIO_puts(out, "\n"); } else if (enddate == i) { BIO_puts(out, "notAfter="); ASN1_TIME_print(out, X509_get_notAfter(x)); BIO_puts(out, "\n"); } else if (fingerprint == i) { int j; unsigned int n; unsigned char md[EVP_MAX_MD_SIZE]; const EVP_MD *fdig = digest; if (!fdig) fdig = EVP_sha1(); if (!X509_digest(x, fdig, md, &n)) { BIO_printf(bio_err, "out of memory\n"); goto end; } BIO_printf(out, "%s Fingerprint=", OBJ_nid2sn(EVP_MD_type(fdig))); for (j = 0; j < (int)n; j++) { BIO_printf(out, "%02X%c", md[j], (j + 1 == (int)n) ? '\n' : ':'); } } /* should be in the library */ else if ((sign_flag == i) && (x509req == 0)) { BIO_printf(bio_err, "Getting Private key\n"); if (Upkey == NULL) { Upkey = load_key(keyfile, keyformat, 0, passin, e, "Private key"); if (Upkey == NULL) goto end; } assert(need_rand); if (!sign(x, Upkey, days, clrext, digest, extconf, extsect)) goto end; } else if (CA_flag == i) { BIO_printf(bio_err, "Getting CA Private Key\n"); if (CAkeyfile != NULL) { CApkey = load_key(CAkeyfile, CAkeyformat, 0, passin, e, "CA Private Key"); if (CApkey == NULL) goto end; } assert(need_rand); if (!x509_certify(ctx, CAfile, digest, x, xca, CApkey, sigopts, CAserial, CA_createserial, days, clrext, extconf, extsect, sno, reqfile)) goto end; } else if (x509req == i) { EVP_PKEY *pk; BIO_printf(bio_err, "Getting request Private Key\n"); if (keyfile == NULL) { BIO_printf(bio_err, "no request key file specified\n"); goto end; } else { pk = load_key(keyfile, keyformat, 0, passin, e, "request key"); if (pk == NULL) goto end; } BIO_printf(bio_err, "Generating certificate request\n"); rq = X509_to_X509_REQ(x, pk, digest); EVP_PKEY_free(pk); if (rq == NULL) { ERR_print_errors(bio_err); goto end; } if (!noout) { X509_REQ_print(out, rq); PEM_write_bio_X509_REQ(out, rq); } noout = 1; } else if (ocspid == i) { X509_ocspid_print(out, x); } } } if (checkend) { time_t tcheck = time(NULL) + checkoffset; if (X509_cmp_time(X509_get_notAfter(x), &tcheck) < 0) { BIO_printf(out, "Certificate will expire\n"); ret = 1; } else { BIO_printf(out, "Certificate will not expire\n"); ret = 0; } goto end; } print_cert_checks(out, x, checkhost, checkemail, checkip); if (noout || nocert) { ret = 0; goto end; } if (badsig) x->signature->data[x->signature->length - 1] ^= 0x1; if (outformat == FORMAT_ASN1) i = i2d_X509_bio(out, x); else if (outformat == FORMAT_PEM) { if (trustout) i = PEM_write_bio_X509_AUX(out, x); else i = PEM_write_bio_X509(out, x); } else if (outformat == FORMAT_NETSCAPE) { NETSCAPE_X509 nx; ASN1_OCTET_STRING hdr; hdr.data = (unsigned char *)NETSCAPE_CERT_HDR; hdr.length = strlen(NETSCAPE_CERT_HDR); nx.header = &hdr; nx.cert = x; i = ASN1_item_i2d_bio(ASN1_ITEM_rptr(NETSCAPE_X509), out, &nx); } else { BIO_printf(bio_err, "bad output format specified for outfile\n"); goto end; } if (!i) { BIO_printf(bio_err, "unable to write certificate\n"); ERR_print_errors(bio_err); goto end; } ret = 0; end: if (need_rand) app_RAND_write_file(NULL); OBJ_cleanup(); NCONF_free(extconf); BIO_free_all(out); X509_STORE_free(ctx); X509_REQ_free(req); X509_free(x); X509_free(xca); EVP_PKEY_free(Upkey); EVP_PKEY_free(CApkey); EVP_PKEY_free(fkey); sk_OPENSSL_STRING_free(sigopts); X509_REQ_free(rq); ASN1_INTEGER_free(sno); sk_ASN1_OBJECT_pop_free(trust, ASN1_OBJECT_free); sk_ASN1_OBJECT_pop_free(reject, ASN1_OBJECT_free); OPENSSL_free(passin); return (ret); }
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; }
static int autoca_gencert( Operation *op, genargs *args ) { X509_NAME *subj_name, *issuer_name; X509 *subj_cert; struct berval derdn; unsigned char *pp; EVP_PKEY *evpk = NULL; int rc; if ((subj_cert = X509_new()) == NULL) return -1; autoca_dnbv2der( op, args->subjectDN, &derdn ); pp = (unsigned char *)derdn.bv_val; subj_name = d2i_X509_NAME( NULL, (const unsigned char **)&pp, derdn.bv_len ); op->o_tmpfree( derdn.bv_val, op->o_tmpmemctx ); if ( subj_name == NULL ) { fail1: X509_free( subj_cert ); return -1; } rc = autoca_genpkey( args->keybits, &evpk ); if ( rc <= 0 ) { fail2: if ( subj_name ) X509_NAME_free( subj_name ); goto fail1; } /* encode DER in PKCS#8 */ { PKCS8_PRIV_KEY_INFO *p8inf; if (( p8inf = EVP_PKEY2PKCS8( evpk )) == NULL ) goto fail2; args->derpkey.bv_len = i2d_PKCS8_PRIV_KEY_INFO( p8inf, NULL ); args->derpkey.bv_val = op->o_tmpalloc( args->derpkey.bv_len, op->o_tmpmemctx ); pp = (unsigned char *)args->derpkey.bv_val; i2d_PKCS8_PRIV_KEY_INFO( p8inf, &pp ); PKCS8_PRIV_KEY_INFO_free( p8inf ); } args->newpkey = evpk; /* set random serial */ { BIGNUM *bn = BN_new(); if ( bn == NULL ) { fail3: EVP_PKEY_free( evpk ); goto fail2; } if (!BN_pseudo_rand(bn, SERIAL_BITS, 0, 0)) { BN_free( bn ); goto fail3; } if (!BN_to_ASN1_INTEGER(bn, X509_get_serialNumber(subj_cert))) { BN_free( bn ); goto fail3; } BN_free(bn); } if (args->issuer_cert) { issuer_name = X509_get_subject_name(args->issuer_cert); } else { issuer_name = subj_name; args->issuer_cert = subj_cert; args->issuer_pkey = evpk; } if (!X509_set_version(subj_cert, 2) || /* set version to V3 */ !X509_set_issuer_name(subj_cert, issuer_name) || !X509_set_subject_name(subj_cert, subj_name) || !X509_gmtime_adj(X509_get_notBefore(subj_cert), 0) || !X509_time_adj_ex(X509_get_notAfter(subj_cert), args->days, 0, NULL) || !X509_set_pubkey(subj_cert, evpk)) { goto fail3; } X509_NAME_free(subj_name); subj_name = NULL; /* set cert extensions */ { X509V3_CTX ctx; X509_EXTENSION *ext; int i; X509V3_set_ctx(&ctx, args->issuer_cert, subj_cert, NULL, NULL, 0); for (i=0; args->cert_exts[i].name; i++) { ext = X509V3_EXT_nconf(NULL, &ctx, args->cert_exts[i].name, args->cert_exts[i].value); if ( ext == NULL ) goto fail3; rc = X509_add_ext(subj_cert, ext, -1); X509_EXTENSION_free(ext); if ( !rc ) goto fail3; } if (args->more_exts) { for (i=0; args->more_exts[i].name; i++) { ext = X509V3_EXT_nconf(NULL, &ctx, args->more_exts[i].name, args->more_exts[i].value); if ( ext == NULL ) goto fail3; rc = X509_add_ext(subj_cert, ext, -1); X509_EXTENSION_free(ext); if ( !rc ) goto fail3; } } } rc = autoca_signcert( subj_cert, args->issuer_pkey ); if ( rc < 0 ) goto fail3; args->dercert.bv_len = i2d_X509( subj_cert, NULL ); args->dercert.bv_val = op->o_tmpalloc( args->dercert.bv_len, op->o_tmpmemctx ); pp = (unsigned char *)args->dercert.bv_val; i2d_X509( subj_cert, &pp ); args->newcert = subj_cert; return 0; }
/* * Create a fake X509v3 certificate, signed by the provided CA, * based on the original certificate retrieved from the real server. * The returned certificate is created using X509_new() and thus must * be freed by the caller using X509_free(). * The optional argument extraname is added to subjectAltNames if provided. */ X509 * ssl_x509_forge(X509 *cacrt, EVP_PKEY *cakey, X509 *origcrt, const char *extraname, EVP_PKEY *key) { X509_NAME *subject, *issuer; GENERAL_NAMES *names; GENERAL_NAME *gn; X509 *crt; subject = X509_get_subject_name(origcrt); issuer = X509_get_subject_name(cacrt); if (!subject || !issuer) return NULL; crt = X509_new(); if (!crt) return NULL; if (!X509_set_version(crt, 0x02) || !X509_set_subject_name(crt, subject) || !X509_set_issuer_name(crt, issuer) || ssl_x509_serial_copyrand(crt, origcrt) == -1 || !X509_gmtime_adj(X509_get_notBefore(crt), (long)-60*60*24) || !X509_gmtime_adj(X509_get_notAfter(crt), (long)60*60*24*364) || !X509_set_pubkey(crt, key)) goto errout; /* add standard v3 extensions; cf. RFC 2459 */ X509V3_CTX ctx; X509V3_set_ctx(&ctx, cacrt, crt, NULL, NULL, 0); if (ssl_x509_v3ext_add(&ctx, crt, "basicConstraints", "CA:FALSE") == -1 || ssl_x509_v3ext_add(&ctx, crt, "keyUsage", "digitalSignature," "keyEncipherment") == -1 || ssl_x509_v3ext_add(&ctx, crt, "extendedKeyUsage", "serverAuth") == -1 || ssl_x509_v3ext_add(&ctx, crt, "subjectKeyIdentifier", "hash") == -1 || ssl_x509_v3ext_add(&ctx, crt, "authorityKeyIdentifier", "keyid,issuer:always") == -1) goto errout; if (!extraname) { /* no extraname provided: copy original subjectAltName ext */ if (ssl_x509_v3ext_copy_by_nid(crt, origcrt, NID_subject_alt_name) == -1) goto errout; } else { names = X509_get_ext_d2i(origcrt, NID_subject_alt_name, 0, 0); if (!names) { /* no subjectAltName present: add new one */ char *cfval; if (asprintf(&cfval, "DNS:%s", extraname) < 0) goto errout; if (ssl_x509_v3ext_add(&ctx, crt, "subjectAltName", cfval) == -1) { free(cfval); goto errout; } free(cfval); } else { /* add extraname to original subjectAltName * and add it to the new certificate */ gn = GENERAL_NAME_new(); if (!gn) goto errout2; gn->type = GEN_DNS; gn->d.dNSName = M_ASN1_IA5STRING_new(); if (!gn->d.dNSName) goto errout3; ASN1_STRING_set(gn->d.dNSName, (unsigned char *)extraname, strlen(extraname)); sk_GENERAL_NAME_push(names, gn); X509_EXTENSION *ext = X509V3_EXT_i2d( NID_subject_alt_name, 0, names); if (!X509_add_ext(crt, ext, -1)) { if (ext) { X509_EXTENSION_free(ext); } goto errout3; } X509_EXTENSION_free(ext); sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free); } } #ifdef DEBUG_CERTIFICATE ssl_x509_v3ext_add(&ctx, crt, "nsComment", "Generated by " PNAME); #endif /* DEBUG_CERTIFICATE */ const EVP_MD *md; switch (EVP_PKEY_type(cakey->type)) { #ifndef OPENSSL_NO_RSA case EVP_PKEY_RSA: md = EVP_sha1(); break; #endif /* !OPENSSL_NO_RSA */ #ifndef OPENSSL_NO_DSA case EVP_PKEY_DSA: md = EVP_dss1(); break; #endif /* !OPENSSL_NO_DSA */ #ifndef OPENSSL_NO_ECDSA case EVP_PKEY_EC: md = EVP_ecdsa(); break; #endif /* !OPENSSL_NO_ECDSA */ default: goto errout; } if (!X509_sign(crt, cakey, md)) goto errout; return crt; errout3: GENERAL_NAME_free(gn); errout2: sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free); errout: X509_free(crt); return NULL; }
PKI_X509_CERT * PKI_X509_CERT_new (const PKI_X509_CERT * ca_cert, const PKI_X509_KEYPAIR * kPair, const PKI_X509_REQ * req, const char * subj_s, const char * serial_s, uint64_t validity, const PKI_X509_PROFILE * conf, const PKI_ALGOR * algor, const PKI_CONFIG * oids, HSM *hsm ) { PKI_X509_CERT *ret = NULL; PKI_X509_CERT_VALUE *val = NULL; PKI_X509_NAME *subj = NULL; PKI_X509_NAME *issuer = NULL; PKI_DIGEST_ALG *digest = NULL; PKI_X509_KEYPAIR_VALUE *signingKey = NULL; PKI_TOKEN *tk = NULL; PKI_X509_KEYPAIR_VALUE *certPubKeyVal = NULL; int rv = 0; int ver = 2; int64_t notBeforeVal = 0; ASN1_INTEGER *serial = NULL; char *ver_s = NULL; /* Check if the REQUIRED PKEY has been passed */ if (!kPair || !kPair->value) { PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); return (NULL); }; signingKey = kPair->value; /* TODO: This has to be fixed, to work on every option */ if ( subj_s ) { subj = PKI_X509_NAME_new ( subj_s ); } else if (conf || req) { char *tmp_s = NULL; // Let's use the configuration option first if (conf) { // Get the value of the DN, if present if ((tmp_s = PKI_CONFIG_get_value( conf, "/profile/subject/dn")) != NULL ) { // Builds from the DN in the config subj = PKI_X509_NAME_new(tmp_s); PKI_Free ( tmp_s ); } } // If we still do not have a name, let's check // the request for one if (req && !subj) { const PKI_X509_NAME * req_subj = NULL; // Copy the name from the request if ((req_subj = PKI_X509_REQ_get_data(req, PKI_X509_DATA_SUBJECT)) != NULL) { subj = PKI_X509_NAME_dup(req_subj); } } // If no name is provided, let's use an empty one // TODO: Shall we remove this and fail instead ? if (!subj) subj = PKI_X509_NAME_new( "" ); } else { struct utsname myself; char tmp_name[1024]; if (uname(&myself) < 0) { subj = PKI_X509_NAME_new( "" ); } else { sprintf( tmp_name, "CN=%s", myself.nodename ); subj = PKI_X509_NAME_new( tmp_name ); } } if (!subj) { PKI_ERROR(PKI_ERR_X509_CERT_CREATE_SUBJECT, subj_s ); goto err; } if( ca_cert ) { const PKI_X509_NAME *ca_subject = NULL; /* Let's get the ca_cert subject and dup that data */ // ca_subject = (PKI_X509_NAME *) // X509_get_subject_name( (X509 *) ca_cert ); ca_subject = PKI_X509_CERT_get_data( ca_cert, PKI_X509_DATA_SUBJECT ); if( ca_subject ) { issuer = (PKI_X509_NAME *) X509_NAME_dup((X509_NAME *)ca_subject); } else { PKI_ERROR(PKI_ERR_X509_CERT_CREATE_ISSUER, NULL); goto err; } } else { issuer = (PKI_X509_NAME *) X509_NAME_dup((X509_NAME *) subj); } if( !issuer ) { PKI_ERROR(PKI_ERR_X509_CERT_CREATE_ISSUER, NULL); goto err; } if(( ret = PKI_X509_CERT_new_null()) == NULL ) { PKI_ERROR(PKI_ERR_OBJECT_CREATE, NULL); goto err; } /* Alloc memory structure for the Certificate */ if((ret->value = ret->cb->create()) == NULL ) { PKI_ERROR(PKI_ERR_OBJECT_CREATE, NULL); return (NULL); } val = ret->value; if(( ver_s = PKI_CONFIG_get_value( conf, "/profile/version")) != NULL ) { ver = atoi( ver_s ) - 1; if ( ver < 0 ) ver = 0; PKI_Free ( ver_s ); } else { ver = 2; }; if (!X509_set_version(val,ver)) { PKI_ERROR(PKI_ERR_X509_CERT_CREATE_VERSION, NULL); goto err; } if (serial_s) { char * tmp_s = (char *) serial_s; serial = s2i_ASN1_INTEGER(NULL, tmp_s); } else { // If cacert we assume it is a normal cert - let's create a // random serial number, otherwise - it's a self-signed, use // the usual 'fake' 0 if ( ca_cert ) { unsigned char bytes[11]; RAND_bytes(bytes, sizeof(bytes)); bytes[0] = 0; serial = PKI_INTEGER_new_bin(bytes, sizeof(bytes)); } else { serial = s2i_ASN1_INTEGER( NULL, "0"); }; }; if(!X509_set_serialNumber( val, serial )) { PKI_ERROR(PKI_ERR_X509_CERT_CREATE_SERIAL, serial_s); goto err; } /* Set the issuer Name */ // rv = X509_set_issuer_name((X509 *) ret, (X509_NAME *) issuer); if(!X509_set_issuer_name( val, (X509_NAME *) issuer)) { PKI_ERROR(PKI_ERR_X509_CERT_CREATE_ISSUER, NULL); goto err; } /* Set the subject Name */ if(!X509_set_subject_name(val, (X509_NAME *) subj)) { PKI_ERROR(PKI_ERR_X509_CERT_CREATE_SUBJECT, NULL); goto err; } /* Set the start date (notBefore) */ if (conf) { int years = 0; int days = 0; int hours = 0; int mins = 0; int secs = 0; char *tmp_s = NULL; if(( tmp_s = PKI_CONFIG_get_value( conf, "/profile/notBefore/years")) != NULL ) { years = atoi( tmp_s ); PKI_Free ( tmp_s ); }; if(( tmp_s = PKI_CONFIG_get_value( conf, "/profile/notBefore/days")) != NULL ) { days = atoi( tmp_s ); PKI_Free ( tmp_s ); }; if(( tmp_s = PKI_CONFIG_get_value( conf, "/profile/notBefore/hours")) != NULL ) { hours = atoi( tmp_s ); PKI_Free ( tmp_s ); }; if(( tmp_s = PKI_CONFIG_get_value( conf, "/profile/notBefore/minutes")) != NULL ) { mins = atoi( tmp_s ); PKI_Free ( tmp_s ); }; if(( tmp_s = PKI_CONFIG_get_value( conf, "/profile/notBefore/seconds")) != NULL ) { secs = atoi( tmp_s ); PKI_Free ( tmp_s ); }; notBeforeVal = secs + ( mins * 60 ) + ( hours * 3600 ) + ( days * 3600 * 24 ) + ( years * 3600 * 24 * 365 ); }; /* Set the validity (notAfter) */ if( conf && validity == 0 ) { long long years = 0; long long days = 0; long long hours = 0; long long mins = 0; long long secs = 0; char *tmp_s = NULL; if(( tmp_s = PKI_CONFIG_get_value( conf, "/profile/validity/years")) != NULL ) { years = atoll( tmp_s ); PKI_Free ( tmp_s ); }; if(( tmp_s = PKI_CONFIG_get_value( conf, "/profile/validity/days")) != NULL ) { days = atoll( tmp_s ); PKI_Free ( tmp_s ); }; if(( tmp_s = PKI_CONFIG_get_value( conf, "/profile/validity/hours")) != NULL ) { hours = atoll( tmp_s ); PKI_Free ( tmp_s ); }; if(( tmp_s = PKI_CONFIG_get_value( conf, "/profile/validity/minutes")) != NULL ) { mins = atoll( tmp_s ); PKI_Free ( tmp_s ); }; if(( tmp_s = PKI_CONFIG_get_value( conf, "/profile/validity/minutes")) != NULL ) { secs = atoll( tmp_s ); PKI_Free ( tmp_s ); }; validity = (unsigned long long) secs + (unsigned long long) ( mins * 60 ) + (unsigned long long) ( hours * 3600 ) + (unsigned long long) ( days * 3600 * 24 ) + (unsigned long long) ( years * 3600 * 24 * 365 ); }; if (validity <= 0) validity = 30 * 3600 * 24; #if ( LIBPKI_OS_BITS == LIBPKI_OS32 ) long notBeforeVal32 = (long) notBeforeVal; if (X509_gmtime_adj(X509_get_notBefore(val), notBeforeVal32 ) == NULL) { #else if (X509_gmtime_adj(X509_get_notBefore(val), notBeforeVal ) == NULL) { #endif PKI_ERROR(PKI_ERR_X509_CERT_CREATE_NOTBEFORE, NULL); goto err; } /* Set the end date in a year */ if (X509_gmtime_adj(X509_get_notAfter(val),(long int) validity) == NULL) { PKI_DEBUG("ERROR: can not set notAfter field!"); goto err; } /* Copy the PKEY if it is in the request, otherwise use the public part of the PKI_X509_CERT */ if (req) { certPubKeyVal = (PKI_X509_KEYPAIR_VALUE *) PKI_X509_REQ_get_data(req, PKI_X509_DATA_KEYPAIR_VALUE); if( !certPubKeyVal ) { PKI_DEBUG("ERROR, can not get pubkey from req!"); goto err; } } else { /* Self Signed -- Same Public Key! */ certPubKeyVal = signingKey; } if (!ca_cert && conf) { char *tmp_s = NULL; if(( tmp_s = PKI_X509_PROFILE_get_value( conf, "/profile/keyParams/algorithm")) != NULL ) { PKI_ALGOR *myAlg = NULL; PKI_DIGEST_ALG *dgst = NULL; if((myAlg = PKI_ALGOR_get_by_name( tmp_s )) != NULL ) { if(!algor) algor = myAlg; if((dgst = PKI_ALGOR_get_digest( myAlg )) != NULL ) { PKI_DEBUG("Got Signing Algorithm: %s, %s", PKI_DIGEST_ALG_get_parsed(dgst), PKI_ALGOR_get_parsed(myAlg)); digest = dgst; } else { PKI_DEBUG("Can not parse digest algorithm from %s", tmp_s); } } else { PKI_DEBUG("Can not parse key algorithm from %s", tmp_s); } PKI_Free ( tmp_s ); } } if (conf) { PKI_KEYPARAMS *kParams = NULL; PKI_SCHEME_ID scheme; scheme = PKI_ALGOR_get_scheme( algor ); kParams = PKI_KEYPARAMS_new(scheme, conf); if (kParams) { /* Sets the point compression */ switch ( kParams->scheme ) { #ifdef ENABLE_ECDSA case PKI_SCHEME_ECDSA: if ( (int) kParams->ec.form > 0 ) { # if OPENSSL_VERSION_NUMBER < 0x1010000fL EC_KEY_set_conv_form(certPubKeyVal->pkey.ec, (point_conversion_form_t) kParams->ec.form); # else EC_KEY_set_conv_form(EVP_PKEY_get0_EC_KEY(certPubKeyVal), (point_conversion_form_t) kParams->ec.form); # endif } if ( kParams->ec.asn1flags > -1 ) { # if OPENSSL_VERSION_NUMBER < 0x1010000fL EC_KEY_set_asn1_flag(certPubKeyVal->pkey.ec, kParams->ec.asn1flags ); # else EC_KEY_set_asn1_flag(EVP_PKEY_get0_EC_KEY(certPubKeyVal), kParams->ec.asn1flags ); # endif } break; #endif case PKI_SCHEME_RSA: case PKI_SCHEME_DSA: break; default: // Nothing to do PKI_ERROR(PKI_ERR_GENERAL, "Signing Scheme Uknown %d!", kParams->scheme); break; } } } if (!X509_set_pubkey(val, certPubKeyVal)) { PKI_DEBUG("ERROR, can not set pubkey in cert!"); goto err; } if (conf) { if((tk = PKI_TOKEN_new_null()) == NULL ) { PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); goto err; } PKI_TOKEN_set_cert(tk, ret); if (ca_cert) { PKI_TOKEN_set_cacert(tk, (PKI_X509_CERT *)ca_cert); } else { PKI_TOKEN_set_cacert(tk, (PKI_X509_CERT *)ret); } if (req) PKI_TOKEN_set_req(tk, (PKI_X509_REQ *)req ); if (kPair) PKI_TOKEN_set_keypair ( tk, (PKI_X509_KEYPAIR *)kPair ); rv = PKI_X509_EXTENSIONS_cert_add_profile(conf, oids, ret, tk); if (rv != PKI_OK) { PKI_DEBUG( "ERROR, can not set extensions!"); tk->cert = NULL; tk->cacert = NULL; tk->req = NULL; tk->keypair = NULL; PKI_TOKEN_free ( tk ); goto err; } // Cleanup for the token (used only to add extensions) tk->cert = NULL; tk->cacert = NULL; tk->req = NULL; tk->keypair = NULL; PKI_TOKEN_free ( tk ); } if (!digest) { if (!algor) { PKI_log_debug("Getting the Digest Algorithm from the CA cert"); // Let's get the Digest Algorithm from the CA Cert if (ca_cert) { if((algor = PKI_X509_CERT_get_data(ca_cert, PKI_X509_DATA_ALGORITHM )) == NULL) { PKI_log_err("Can not retrieve DATA algorithm from CA cert"); } } } // If we have an Algor from either the passed argument or // the CA Certificate, extract the digest from it. Otherwise // get the digest from the signing key if (algor) { if((digest = PKI_ALGOR_get_digest(algor)) == NULL ) { PKI_log_err("Can not get digest from algor"); } } // Check, if still no digest, let's try from the signing Key if (digest == NULL) { if ((digest = PKI_DIGEST_ALG_get_by_key( kPair )) == NULL) { PKI_log_err("Can not infer digest algor from the key pair"); } } } // No Digest Here ? We failed... if (digest == NULL) { PKI_log_err("PKI_X509_CERT_new()::Can not get the digest!"); return( NULL ); } // Sign the data if (PKI_X509_sign(ret, digest, kPair) == PKI_ERR) { PKI_log_err ("Can not sign certificate [%s]", ERR_error_string(ERR_get_error(), NULL )); PKI_X509_CERT_free ( ret ); return NULL; } #if ( OPENSSL_VERSION_NUMBER >= 0x0090900f ) # if OPENSSL_VERSION_NUMBER < 0x1010000fL PKI_X509_CERT_VALUE *cVal = (PKI_X509_CERT_VALUE *) ret->value; if (cVal && cVal->cert_info) { PKI_log_debug("Signature = %s", PKI_ALGOR_get_parsed(cVal->cert_info->signature)); } # endif // PKI_X509_CINF_FULL *cFull = NULL; // cFull = (PKI_X509_CINF_FULL *) cVal->cert_info; // cFull->enc.modified = 1; #endif return ret; err: if (ret) PKI_X509_CERT_free(ret); if (subj) PKI_X509_NAME_free(subj); if (issuer) PKI_X509_NAME_free(issuer); return NULL; } /*! * \brief Signs a PKI_X509_CERT */ int PKI_X509_CERT_sign(PKI_X509_CERT *cert, PKI_X509_KEYPAIR *kp, PKI_DIGEST_ALG *digest) { const PKI_ALGOR *alg = NULL; if( !cert || !cert->value || !kp || !kp->value ) { PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); return PKI_ERR; } if(!digest) { if((alg = PKI_X509_CERT_get_data(cert, PKI_X509_DATA_ALGORITHM))!=NULL) { digest = PKI_ALGOR_get_digest ( alg ); } } if(!digest) { if((digest = PKI_DIGEST_ALG_get_by_key(kp)) == NULL) { PKI_log_err("PKI_X509_CERT_new()::Can not get digest algor " "from key"); return PKI_ERR; } } if( PKI_X509_sign(cert, digest, kp) == PKI_ERR) { PKI_log_err ("PKI_X509_CERT_new()::Can not sign certificate [%s]", ERR_error_string(ERR_get_error(), NULL )); return PKI_ERR; } return PKI_OK; }; /*! * \brief Signs a PKI_X509_CERT by using a configured PKI_TOKEN */ int PKI_X509_CERT_sign_tk ( PKI_X509_CERT *cert, PKI_TOKEN *tk, PKI_DIGEST_ALG *digest) { PKI_X509_KEYPAIR *kp = NULL; if( !cert || !cert->value || !tk ) { PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); return PKI_ERR; }; if( PKI_TOKEN_login( tk ) == PKI_ERR ) { PKI_ERROR(PKI_ERR_HSM_LOGIN, NULL); return PKI_ERR; }; if((kp = PKI_TOKEN_get_keypair( tk )) == NULL ) { return PKI_ERR; }; return PKI_X509_CERT_sign ( cert, kp, digest ); };
int PKI_X509_CERT_set_data(PKI_X509_CERT *x, int type, void *data) { long *aLong = NULL; PKI_TIME *aTime = NULL; PKI_INTEGER *aInt = NULL; PKI_X509_NAME *aName = NULL; PKI_X509_KEYPAIR_VALUE *aKey = NULL; int ret = 0; PKI_X509_CERT_VALUE *xVal = NULL; if( !x || !x->value || !data) { PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); return (PKI_ERR); } xVal = PKI_X509_get_value( x ); switch( type ) { case PKI_X509_DATA_VERSION: aLong = (long *) data; ret = X509_set_version( xVal, *aLong ); break; case PKI_X509_DATA_SERIAL: aInt = (PKI_INTEGER *) data; ret = X509_set_serialNumber( xVal, aInt); break; case PKI_X509_DATA_SUBJECT: aName = (PKI_X509_NAME *) data; ret = X509_set_subject_name( xVal, aName ); break; case PKI_X509_DATA_ISSUER: aName = (PKI_X509_NAME *) data; ret = X509_set_issuer_name( xVal, aName ); break; case PKI_X509_DATA_NOTBEFORE: aTime = (PKI_TIME *) data; ret = X509_set_notBefore( xVal, aTime ); break; case PKI_X509_DATA_NOTAFTER: aTime = (PKI_TIME *) data; ret = X509_set_notAfter( xVal, aTime ); break; case PKI_X509_DATA_KEYPAIR_VALUE: aKey = data; ret = X509_set_pubkey( xVal, aKey); break; case PKI_X509_DATA_ALGORITHM: case PKI_X509_DATA_SIGNATURE_ALG1: if (xVal->cert_info != NULL) { // if (xVal->cert_info->signature != NULL) X509_ALGOR_free(xVal->cert_info->signature); xVal->cert_info->signature = (X509_ALGOR *) data; } break; case PKI_X509_DATA_SIGNATURE_ALG2: // if (xVal->sig_alg != NULL ) X509_ALGOR_free(xVal->sig_alg); xVal->sig_alg = (X509_ALGOR *) data; break; default: /* Not Recognized/Supported DATATYPE */ ret = 0; break; } if (!ret) return PKI_ERR; return PKI_OK; }
/** Generate and sign an X509 certificate with the public key <b>rsa</b>, * signed by the private key <b>rsa_sign</b>. The commonName of the * certificate will be <b>cname</b>; the commonName of the issuer will be * <b>cname_sign</b>. The cert will be valid for <b>cert_lifetime</b> seconds * starting from now. Return a certificate on success, NULL on * failure. */ static X509 * tor_tls_create_certificate(crypto_pk_env_t *rsa, crypto_pk_env_t *rsa_sign, const char *cname, const char *cname_sign, unsigned int cert_lifetime) { time_t start_time, end_time; EVP_PKEY *sign_pkey = NULL, *pkey=NULL; X509 *x509 = NULL; X509_NAME *name = NULL, *name_issuer=NULL; tor_tls_init(); start_time = time(NULL); tor_assert(rsa); tor_assert(cname); tor_assert(rsa_sign); tor_assert(cname_sign); if (!(sign_pkey = _crypto_pk_env_get_evp_pkey(rsa_sign,1))) goto error; if (!(pkey = _crypto_pk_env_get_evp_pkey(rsa,0))) goto error; if (!(x509 = X509_new())) goto error; if (!(X509_set_version(x509, 2))) goto error; if (!(ASN1_INTEGER_set(X509_get_serialNumber(x509), (long)start_time))) goto error; if (!(name = tor_x509_name_new(cname))) goto error; if (!(X509_set_subject_name(x509, name))) goto error; if (!(name_issuer = tor_x509_name_new(cname_sign))) goto error; if (!(X509_set_issuer_name(x509, name_issuer))) goto error; if (!X509_time_adj(X509_get_notBefore(x509),0,&start_time)) goto error; end_time = start_time + cert_lifetime; if (!X509_time_adj(X509_get_notAfter(x509),0,&end_time)) goto error; if (!X509_set_pubkey(x509, pkey)) goto error; if (!X509_sign(x509, sign_pkey, EVP_sha1())) goto error; goto done; error: if (x509) { X509_free(x509); x509 = NULL; } done: tls_log_errors(NULL, LOG_WARN, "generating certificate"); if (sign_pkey) EVP_PKEY_free(sign_pkey); if (pkey) EVP_PKEY_free(pkey); if (name) X509_NAME_free(name); if (name_issuer) X509_NAME_free(name_issuer); return x509; }
/*============================================================================ * OpcUa_P_OpenSSL_X509_SelfSigned_Custom_Create *===========================================================================*/ OpcUa_StatusCode OpcUa_P_OpenSSL_X509_SelfSigned_Custom_Create( OpcUa_CryptoProvider* a_pProvider, OpcUa_Int32 a_serialNumber, OpcUa_UInt32 a_validToInSec, OpcUa_Crypto_NameEntry* a_pNameEntries, /* will be used for issuer and subject thus it's selfigned cert */ OpcUa_UInt a_nameEntriesCount, /* will be used for issuer and subject thus it's selfigned cert */ OpcUa_Key a_pSubjectPublicKey, /* EVP_PKEY* - type defines also public key algorithm */ OpcUa_Crypto_Extension* a_pExtensions, OpcUa_UInt a_extensionsCount, OpcUa_UInt a_signatureHashAlgorithm, /* EVP_sha1(),... */ OpcUa_Key a_pIssuerPrivateKey, /* EVP_PKEY* - type defines also signature algorithm */ OpcUa_ByteString* a_pCertificate) { OpcUa_UInt i; X509_NAME* pSubj = OpcUa_Null; X509V3_CTX ctx; const EVP_MD* pDigest = OpcUa_Null; X509* pCert = OpcUa_Null; EVP_PKEY* pSubjectPublicKey = OpcUa_Null; EVP_PKEY* pIssuerPrivateKey = OpcUa_Null; OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "X509_SelfSigned_Custom_Create"); OpcUa_ReferenceParameter(a_pProvider); OpcUa_ReturnErrorIfArgumentNull(a_pNameEntries); OpcUa_ReturnErrorIfArgumentNull(a_pExtensions); OpcUa_ReturnErrorIfArgumentNull(a_pIssuerPrivateKey.Key.Data); OpcUa_ReturnErrorIfArgumentNull(a_pCertificate); if(a_pSubjectPublicKey.Type != OpcUa_Crypto_KeyType_Rsa_Public) { uStatus = OpcUa_BadInvalidArgument; OpcUa_GotoErrorIfBad(uStatus); } if(a_pIssuerPrivateKey.Type != OpcUa_Crypto_KeyType_Rsa_Private) { uStatus = OpcUa_BadInvalidArgument; OpcUa_GotoErrorIfBad(uStatus); } pSubjectPublicKey = d2i_PublicKey(EVP_PKEY_RSA,OpcUa_Null,((const unsigned char**)&(a_pSubjectPublicKey.Key.Data)),a_pSubjectPublicKey.Key.Length); if(pSubjectPublicKey == OpcUa_Null) { uStatus = OpcUa_Bad; OpcUa_GotoErrorIfBad(uStatus); } pIssuerPrivateKey = d2i_PrivateKey(EVP_PKEY_RSA,OpcUa_Null,((const unsigned char**)&(a_pIssuerPrivateKey.Key.Data)),a_pIssuerPrivateKey.Key.Length); if(pIssuerPrivateKey == OpcUa_Null) { uStatus = OpcUa_Bad; OpcUa_GotoErrorIfBad(uStatus); } /* create new certificate object */ pCert = X509_new(); if(pCert == OpcUa_Null) { uStatus = OpcUa_Bad; OpcUa_GotoErrorIfBad(uStatus); } /* set version of certificate (V3 since internal representation starts versioning from 0) */ if(X509_set_version(pCert, 2L) != 1) { uStatus = OpcUa_Bad; OpcUa_GotoErrorIfBad(uStatus); } /* generate a unique number for a serial number if none provided. */ if(a_serialNumber == 0) { ASN1_INTEGER* pSerialNumber = X509_get_serialNumber(pCert); pSerialNumber->type = V_ASN1_INTEGER; pSerialNumber->data = OPENSSL_realloc(pSerialNumber->data, 16); pSerialNumber->length = 16; if(pSerialNumber->data == NULL || OpcUa_P_Guid_Create((OpcUa_Guid*)pSerialNumber->data) == NULL) { uStatus = OpcUa_Bad; OpcUa_GotoErrorIfBad(uStatus); } } /* use the integer passed in - note the API should not be using a 32-bit integer - must fix sometime */ else if(ASN1_INTEGER_set(X509_get_serialNumber(pCert), a_serialNumber) == 0) { uStatus = OpcUa_Bad; OpcUa_GotoErrorIfBad(uStatus); } /* add key to the request */ if(X509_set_pubkey(pCert, pSubjectPublicKey) != 1) { uStatus = OpcUa_Bad; OpcUa_GotoErrorIfBad(uStatus); } if(pSubjectPublicKey != OpcUa_Null) { EVP_PKEY_free(pSubjectPublicKey); pSubjectPublicKey = OpcUa_Null; } /* assign the subject name */ pSubj = X509_NAME_new(); if(!pSubj) { uStatus = OpcUa_Bad; OpcUa_GotoErrorIfBad(uStatus); } /* create and add entries to subject name */ for(i=0; i<a_nameEntriesCount; i++) { uStatus = OpcUa_P_OpenSSL_X509_Name_AddEntry(&pSubj, a_pNameEntries + i); OpcUa_GotoErrorIfBad(uStatus); } /* set subject name in request */ if(X509_set_subject_name(pCert, pSubj) != 1) { uStatus = OpcUa_Bad; OpcUa_GotoErrorIfBad(uStatus); } /* set name of issuer (CA) */ if(X509_set_issuer_name(pCert, pSubj) != 1) { uStatus = OpcUa_Bad; OpcUa_GotoErrorIfBad(uStatus); } if(!(X509_gmtime_adj(X509_get_notBefore(pCert), 0))) { uStatus = OpcUa_Bad; OpcUa_GotoErrorIfBad(uStatus); } /* set ending time of the certificate */ if(!(X509_gmtime_adj(X509_get_notAfter(pCert), a_validToInSec))) { uStatus = OpcUa_Bad; OpcUa_GotoErrorIfBad(uStatus); } /* add x509v3 extensions */ X509V3_set_ctx(&ctx, pCert, pCert, OpcUa_Null, OpcUa_Null, 0); for(i=0; i<a_extensionsCount; i++) { uStatus = OpcUa_P_OpenSSL_X509_AddCustomExtension(&pCert, a_pExtensions+i, &ctx); OpcUa_GotoErrorIfBad(uStatus); } /* sign certificate with the CA private key */ switch(a_signatureHashAlgorithm) { case OPCUA_P_SHA_160: pDigest = EVP_sha1(); break; case OPCUA_P_SHA_224: pDigest = EVP_sha224(); break; case OPCUA_P_SHA_256: pDigest = EVP_sha256(); break; case OPCUA_P_SHA_384: pDigest = EVP_sha384(); break; case OPCUA_P_SHA_512: pDigest = EVP_sha512(); break; default: uStatus = OpcUa_BadNotSupported; OpcUa_GotoErrorIfBad(uStatus); } if(!(X509_sign(pCert, pIssuerPrivateKey, pDigest))) { uStatus = OpcUa_Bad; OpcUa_GotoErrorIfBad(uStatus); } if(X509_verify(pCert, pIssuerPrivateKey) <= 0) { uStatus = OpcUa_Bad; OpcUa_GotoErrorIfBad(uStatus); } if(pIssuerPrivateKey != OpcUa_Null) { EVP_PKEY_free(pIssuerPrivateKey); pIssuerPrivateKey = OpcUa_Null; } if(pSubj != OpcUa_Null) { X509_NAME_free(pSubj); pSubj = OpcUa_Null; } /* prepare container */ memset(a_pCertificate, 0, sizeof(OpcUa_ByteString)); /* get required length for conversion target buffer */ a_pCertificate->Length = i2d_X509(pCert, NULL); if(a_pCertificate->Length <= 0) { /* conversion to DER not possible */ uStatus = OpcUa_Bad; } /* allocate conversion target buffer */ a_pCertificate->Data = (OpcUa_Byte*)OpcUa_P_Memory_Alloc(a_pCertificate->Length); OpcUa_GotoErrorIfAllocFailed(a_pCertificate->Data); /* convert into DER */ a_pCertificate->Length = i2d_X509(pCert, &(a_pCertificate->Data)); if(a_pCertificate->Length <= 0) { /* conversion to DER not possible */ uStatus = OpcUa_Bad; } else { /* correct pointer incrementation by i2d_X509() */ a_pCertificate->Data -= a_pCertificate->Length; } X509_free(pCert); OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; X509_free(pCert); if(pSubjectPublicKey != OpcUa_Null) { EVP_PKEY_free(pSubjectPublicKey); } if(pIssuerPrivateKey != OpcUa_Null) { EVP_PKEY_free(pIssuerPrivateKey); } if(pSubj != OpcUa_Null) { X509_NAME_free(pSubj); } OpcUa_FinishErrorHandling; }
/* Creates an X509 certificate from a certificate request. */ EXPORT int IssueUserCertificate(unsigned char *certbuf, int *certlen, unsigned char *reqbuf, int reqlen) { X509_REQ *req = NULL; EVP_PKEY *cakey = NULL, *rakey = NULL, *usrkey = NULL; X509 *cacert = NULL, *racert = NULL, *usrcert = NULL; X509_NAME *subject = NULL, *issuer = NULL; unsigned char *p = NULL; int ret = OPENSSLCA_NO_ERR, len; if (certbuf == NULL || certlen == NULL || reqbuf == NULL || reqlen == 0) return OPENSSLCA_ERR_ARGS; /* Decode request */ if ((req = X509_REQ_new()) == NULL) { ret = OPENSSLCA_ERR_REQ_NEW; goto err; } p = reqbuf; if (d2i_X509_REQ(&req, &p, reqlen) == NULL) { ret = OPENSSLCA_ERR_REQ_DECODE; goto err; } /* Get public key from request */ if ((usrkey = X509_REQ_get_pubkey(req)) == NULL) { ret = OPENSSLCA_ERR_REQ_GET_PUBKEY; goto err; } if (caIni.verifyRequests) { /* Get RA's public key */ /* TODO: Validate RA certificate */ ret = read_cert(&racert, CA_PATH(caIni.raCertFile)); if (ret != OPENSSLCA_NO_ERR) goto err; if ((rakey = X509_get_pubkey(racert)) == NULL) { ret = OPENSSLCA_ERR_CERT_GET_PUBKEY; goto err; } /* Verify signature on request */ if (X509_REQ_verify(req, rakey) != 1) { ret = OPENSSLCA_ERR_REQ_VERIFY; goto err; } } /* Get CA certificate */ /* TODO: Validate CA certificate */ ret = read_cert(&cacert, CA_PATH(caIni.caCertFile)); if (ret != OPENSSLCA_NO_ERR) goto err; /* Get CA private key */ ret = read_key(&cakey, CA_PATH(caIni.caKeyFile), caIni.caKeyPasswd); if (ret != OPENSSLCA_NO_ERR) goto err; /* Create user certificate */ if ((usrcert = X509_new()) == NULL) return OPENSSLCA_ERR_CERT_NEW; /* Set version and serial number for certificate */ if (X509_set_version(usrcert, 2) != 1) { /* V3 */ ret = OPENSSLCA_ERR_CERT_SET_VERSION; goto err; } if (ASN1_INTEGER_set(X509_get_serialNumber(usrcert), get_serial()) != 1) { ret = OPENSSLCA_ERR_CERT_SET_SERIAL; goto err; } /* Set duration for certificate */ if (X509_gmtime_adj(X509_get_notBefore(usrcert), 0) == NULL) { ret = OPENSSLCA_ERR_CERT_SET_NOTBEFORE; goto err; } if (X509_gmtime_adj(X509_get_notAfter(usrcert), EXPIRE_SECS(caIni.daysTillExpire)) == NULL) { ret = OPENSSLCA_ERR_CERT_SET_NOTAFTER; goto err; } /* Set public key */ if (X509_set_pubkey(usrcert, usrkey) != 1) { ret = OPENSSLCA_ERR_CERT_SET_PUBKEY; goto err; } /* Set subject name */ subject = X509_REQ_get_subject_name(req); if (subject == NULL) { ret = OPENSSLCA_ERR_REQ_GET_SUBJECT; goto err; } if (X509_set_subject_name(usrcert, subject) != 1) { ret = OPENSSLCA_ERR_CERT_SET_SUBJECT; goto err; } /* Set issuer name */ issuer = X509_get_issuer_name(cacert); if (issuer == NULL) { ret = OPENSSLCA_ERR_CERT_GET_ISSUER; goto err; } if (X509_set_issuer_name(usrcert, issuer) != 1) { ret = OPENSSLCA_ERR_CERT_SET_ISSUER; goto err; } /* Add extensions */ ret = add_ext(cacert, usrcert); if (ret != OPENSSLCA_NO_ERR) goto err; /* Sign user certificate with CA's private key */ if (!X509_sign(usrcert, cakey, EVP_sha1())) return OPENSSLCA_ERR_CERT_SIGN; if (caIni.verifyAfterSign) { if (X509_verify(usrcert, cakey) != 1) { ret = OPENSSLCA_ERR_CERT_VERIFY; goto err; } } #ifdef _DEBUG /* Output certificate in DER and PEM format */ { FILE *fp = fopen(DBG_PATH("usrcert.der"), "wb"); if (fp != NULL) { i2d_X509_fp(fp, usrcert); fclose(fp); } fp = fopen(DBG_PATH("usrcert.pem"), "w"); if (fp != NULL) { X509_print_fp(fp, usrcert); PEM_write_X509(fp, usrcert); fclose(fp); } } #endif /* Encode user certificate into DER format */ len = i2d_X509(usrcert, NULL); if (len < 0) { ret = OPENSSLCA_ERR_CERT_ENCODE; goto err; } if (len > *certlen) { ret = OPENSSLCA_ERR_BUF_TOO_SMALL; goto err; } *certlen = len; p = certbuf; i2d_X509(usrcert, &p); if (caIni.addToIndex) add_to_index(usrcert); if (caIni.addToNewCerts) write_cert(usrcert); err: print_err("IssueUserCertificate()", ret); /* Clean up */ if (cacert) X509_free(cacert); if (cakey) EVP_PKEY_free(cakey); if (racert) X509_free(racert); if (rakey) EVP_PKEY_free(rakey); if (req) X509_REQ_free(req); if (usrcert != NULL) X509_free(usrcert); if (usrkey) EVP_PKEY_free(usrkey); return ret; }
DVT_STATUS CERTIFICATE_CLASS::generateFiles(LOG_CLASS* logger_ptr, const char* signerCredentialsFile_ptr, const char* credentialsPassword_ptr, const char* keyPassword_ptr, const char* keyFile_ptr, const char* certificateFile_ptr) // DESCRIPTION : Generate a certificate and key files from this class. // PRECONDITIONS : // POSTCONDITIONS : // EXCEPTIONS : // NOTES : If signerCredentialsFile_ptr is NULL, a self signed // : certificate will be generated. // : // : Returns: MSG_OK, MSG_LIB_NOT_EXIST, MSG_FILE_NOT_EXIST, // : MSG_ERROR, MSG_INVALID_PASSWORD //<<=========================================================================== { DVT_STATUS ret = MSG_ERROR; unsigned long err; OPENSSL_CLASS* openSsl_ptr; BIO* caBio_ptr = NULL; EVP_PKEY* caPrivateKey_ptr = NULL; X509* caCertificate_ptr = NULL; EVP_PKEY* key_ptr = NULL; X509* cert_ptr = NULL; X509_NAME* name_ptr; time_t effectiveTime; time_t expirationTime; EVP_PKEY* tmpKey_ptr; const EVP_MD *digest_ptr; BIO* pkBio_ptr = NULL; const EVP_CIPHER *cipher_ptr; BIO* certBio_ptr = NULL; // check for the existence of the OpenSSL DLLs openSsl_ptr = OPENSSL_CLASS::getInstance(); if (openSsl_ptr == NULL) { return MSG_LIB_NOT_EXIST; } // clear the error queue ERR_clear_error(); if (signerCredentialsFile_ptr != NULL) { // open the credentials file caBio_ptr = BIO_new(BIO_s_file_internal()); if (caBio_ptr == NULL) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "setting up to read CA credentials file"); goto end; } if (BIO_read_filename(caBio_ptr, signerCredentialsFile_ptr) <= 0) { err = ERR_peek_error(); if ((ERR_GET_LIB(err) == ERR_LIB_SYS) && (ERR_GET_REASON(err) == ERROR_FILE_NOT_FOUND)) { // file does not exist ERR_clear_error(); // eat any errors ret = MSG_FILE_NOT_EXIST; } else { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "opening CA credentials file for reading"); } goto end; } // read the certificate authority's private key caPrivateKey_ptr = PEM_read_bio_PrivateKey(caBio_ptr, NULL, NULL, (void*)credentialsPassword_ptr); if (caPrivateKey_ptr == NULL) { err = ERR_peek_error(); if ((ERR_GET_LIB(err) == ERR_LIB_EVP) && (ERR_GET_REASON(err) == EVP_R_BAD_DECRYPT)) { // bad password ERR_clear_error(); // eat any errors ret = MSG_INVALID_PASSWORD; } else { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "reading private key from CA credentials file"); } goto end; } // read the certificate authority's certificate caCertificate_ptr = PEM_read_bio_X509(caBio_ptr, NULL, NULL, (void*)credentialsPassword_ptr); if (caCertificate_ptr == NULL) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "reading CA certificate from CA credentials file"); goto end; } } // generate the new private/public key pair if (signatureAlgorithmM.compare("RSA") == 0) { // RSA key RSA* rsa_key; rsa_key = RSA_generate_key(signatureKeyLengthM, RSA_3, NULL, 0); if (rsa_key == NULL) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "generating RSA key"); goto end; } key_ptr = EVP_PKEY_new(); if (key_ptr == NULL) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "creating RSA key"); RSA_free(rsa_key); goto end; } EVP_PKEY_assign_RSA(key_ptr, rsa_key); } else { // DSA key DSA* dsa_key; dsa_key = DSA_generate_parameters(signatureKeyLengthM, NULL, 0, NULL, NULL, NULL, 0); if (dsa_key == NULL) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "generating DSA parameters"); goto end; } if (DSA_generate_key(dsa_key) == 0) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "generating DSA key"); DSA_free(dsa_key); goto end; } key_ptr = EVP_PKEY_new(); if (key_ptr == NULL) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "creating DSA key"); DSA_free(dsa_key); goto end; } EVP_PKEY_assign_DSA(key_ptr, dsa_key); } // create the certificate cert_ptr = X509_new(); if (cert_ptr == NULL) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "creating certificate object"); goto end; } // version if (X509_set_version(cert_ptr, (versionM - 1)) != 1) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "setting certificate version"); goto end; } // subject name_ptr = openSsl_ptr->onelineName2Name(subjectM.c_str()); if (name_ptr == NULL) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "parsing owner name"); goto end; } if (X509_set_subject_name(cert_ptr, name_ptr) != 1) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "setting owner name in certificate"); goto end; } // issuer if (signerCredentialsFile_ptr != NULL) { // CA signed name_ptr = X509_get_subject_name(caCertificate_ptr); if (name_ptr == NULL) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "getting name from CA certificate"); goto end; } if (X509_set_issuer_name(cert_ptr, name_ptr) != 1) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "setting issuer name in certificate"); goto end; } } else { // self signed name_ptr = X509_NAME_dup(name_ptr); // duplicate the name so it can be used again if (name_ptr == NULL) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "duplicating owner name"); goto end; } if (X509_set_issuer_name(cert_ptr, name_ptr) != 1) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "setting issuer name in certificate"); goto end; } } // public key if (X509_set_pubkey(cert_ptr, key_ptr) != 1) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "setting public key in certificate"); goto end; } // valid dates effectiveTime = mktime(&effectiveDateM); expirationTime = mktime(&expirationDateM); if ((X509_time_adj(X509_get_notBefore(cert_ptr), 0, &effectiveTime) == NULL) || (X509_time_adj(X509_get_notAfter(cert_ptr), 0, &expirationTime) == NULL)) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "setting valid dates in certificate"); goto end; } // serial number, use the current time_t ASN1_INTEGER_set(X509_get_serialNumber(cert_ptr), (unsigned)time(NULL)); // sign the certificate if (signerCredentialsFile_ptr != NULL) { // CA signed tmpKey_ptr = caPrivateKey_ptr; } else { // self signed tmpKey_ptr = key_ptr; } if (EVP_PKEY_type(tmpKey_ptr->type) == EVP_PKEY_RSA) { digest_ptr = EVP_sha1(); } else if (EVP_PKEY_type(tmpKey_ptr->type) == EVP_PKEY_DSA) { digest_ptr = EVP_dss1(); } else { if (logger_ptr) { logger_ptr->text(LOG_ERROR, 1, "Unsupported key type in CA private key"); } goto end; } if (!X509_sign(cert_ptr, tmpKey_ptr, digest_ptr)) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "signing certificate"); goto end; } // write out the private key // open the private key file pkBio_ptr = BIO_new(BIO_s_file_internal()); if (pkBio_ptr == NULL) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "setting up to write private key file"); goto end; } if (BIO_write_filename(pkBio_ptr, (void *)keyFile_ptr) <= 0) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "opening to write private key file"); goto end; } if ((keyPassword_ptr != NULL) && (strlen(keyPassword_ptr) > 0)) { // we have a password, use 3DES to encrypt the key cipher_ptr = EVP_des_ede3_cbc(); } else { // there is no password, don't encrypt the key cipher_ptr = NULL; } // write out the private key if (PEM_write_bio_PKCS8PrivateKey(pkBio_ptr, key_ptr, cipher_ptr, NULL, 0, NULL, (void *)keyPassword_ptr) != 1) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "writing private key"); goto end; } // write the certificate file // open the certificate file certBio_ptr = BIO_new(BIO_s_file_internal()); if (certBio_ptr == NULL) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "setting up to write certificate file"); goto end; } if (BIO_write_filename(certBio_ptr, (void *)certificateFile_ptr) <= 0) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "opening to write certificate file"); goto end; } // write the new certificate if (PEM_write_bio_X509(certBio_ptr, cert_ptr) != 1) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "writing certificate"); goto end; } // write the new certificate into the credential file if (PEM_write_bio_X509(pkBio_ptr, cert_ptr) != 1) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "writing certificate"); goto end; } if (signerCredentialsFile_ptr != NULL) { // write the CA certificate if (PEM_write_bio_X509(certBio_ptr, caCertificate_ptr) != 1) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "writing CA certificate"); goto end; } // loop reading certificates from the CA credentials file and writing them to the certificate file X509_free(caCertificate_ptr); while ((caCertificate_ptr = PEM_read_bio_X509(caBio_ptr, NULL, NULL, (void*)credentialsPassword_ptr)) != NULL) { // write the certificate if (PEM_write_bio_X509(certBio_ptr, caCertificate_ptr) != 1) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "writing certificate chain"); goto end; } X509_free(caCertificate_ptr); } // check the error err = ERR_peek_error(); if ((ERR_GET_LIB(err) == ERR_LIB_PEM) && (ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) { // end of data - this is normal ERR_clear_error(); } else { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "reading certificates from CA credentials file"); goto end; } } ret = MSG_OK; end: if (certBio_ptr != NULL) BIO_free(certBio_ptr); if (pkBio_ptr != NULL) BIO_free(pkBio_ptr); if (cert_ptr != NULL) X509_free(cert_ptr); if (key_ptr != NULL) EVP_PKEY_free(key_ptr); if (caCertificate_ptr != NULL) X509_free(caCertificate_ptr); if (caPrivateKey_ptr != NULL) EVP_PKEY_free(caPrivateKey_ptr); if (caBio_ptr != NULL) BIO_free(caBio_ptr); return ret; }
static int cert_init() { X509 *x509 = NULL; EVP_PKEY *pkey = NULL; BIGNUM *exponent = NULL, *serial_number = NULL; RSA *rsa = NULL; ASN1_INTEGER *asn1_serial_number; X509_NAME *name; struct dtls_cert *new_cert; ilog(LOG_INFO, "Generating new DTLS certificate"); /* objects */ pkey = EVP_PKEY_new(); exponent = BN_new(); rsa = RSA_new(); serial_number = BN_new(); name = X509_NAME_new(); x509 = X509_new(); if (!exponent || !pkey || !rsa || !serial_number || !name || !x509) goto err; /* key */ if (!BN_set_word(exponent, 0x10001)) goto err; if (!RSA_generate_key_ex(rsa, 1024, exponent, NULL)) goto err; if (!EVP_PKEY_assign_RSA(pkey, rsa)) goto err; /* x509 cert */ if (!X509_set_pubkey(x509, pkey)) goto err; /* serial */ if (!BN_pseudo_rand(serial_number, 64, 0, 0)) goto err; asn1_serial_number = X509_get_serialNumber(x509); if (!asn1_serial_number) goto err; if (!BN_to_ASN1_INTEGER(serial_number, asn1_serial_number)) goto err; /* version 1 */ if (!X509_set_version(x509, 0L)) goto err; /* common name */ if (!X509_NAME_add_entry_by_NID(name, NID_commonName, MBSTRING_UTF8, (unsigned char *) "rtpengine", -1, -1, 0)) goto err; if (!X509_set_subject_name(x509, name)) goto err; if (!X509_set_issuer_name(x509, name)) goto err; /* cert lifetime */ if (!X509_gmtime_adj(X509_get_notBefore(x509), -60*60*24)) goto err; if (!X509_gmtime_adj(X509_get_notAfter(x509), CERT_EXPIRY_TIME)) goto err; /* sign it */ if (!X509_sign(x509, pkey, EVP_sha1())) goto err; /* digest */ new_cert = obj_alloc0("dtls_cert", sizeof(*new_cert), cert_free); new_cert->fingerprint.hash_func = &hash_funcs[0]; dtls_fingerprint_hash(&new_cert->fingerprint, x509); new_cert->x509 = x509; new_cert->pkey = pkey; new_cert->expires = time(NULL) + CERT_EXPIRY_TIME; dump_cert(new_cert); /* swap out certs */ rwlock_lock_w(&__dtls_cert_lock); if (__dtls_cert) obj_put(__dtls_cert); __dtls_cert = new_cert; rwlock_unlock_w(&__dtls_cert_lock); /* cleanup */ BN_free(exponent); BN_free(serial_number); X509_NAME_free(name); return 0; err: ilog(LOG_ERROR, "Failed to generate DTLS certificate"); if (pkey) EVP_PKEY_free(pkey); if (exponent) BN_free(exponent); if (rsa) RSA_free(rsa); if (x509) X509_free(x509); if (serial_number) BN_free(serial_number); return -1; }
int PKI_X509_CERT_set_data(PKI_X509_CERT *x, int type, void *data) { long *aLong = NULL; PKI_TIME *aTime = NULL; PKI_INTEGER *aInt = NULL; PKI_X509_NAME *aName = NULL; PKI_X509_KEYPAIR_VALUE *aKey = NULL; int ret = 0; LIBPKI_X509_CERT *xVal = NULL; LIBPKI_X509_ALGOR *alg = NULL; // PKI_X509_CERT_VALUE *xVal = NULL; if ( !x || !x->value || !data || x->type != PKI_DATATYPE_X509_CERT) { PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); return (PKI_ERR); } // xVal = PKI_X509_get_value( x ); xVal = x->value; switch( type ) { case PKI_X509_DATA_VERSION: aLong = (long *) data; ret = X509_set_version( xVal, *aLong ); break; case PKI_X509_DATA_SERIAL: aInt = (PKI_INTEGER *) data; ret = X509_set_serialNumber( xVal, aInt); break; case PKI_X509_DATA_SUBJECT: aName = (PKI_X509_NAME *) data; ret = X509_set_subject_name( xVal, aName ); break; case PKI_X509_DATA_ISSUER: aName = (PKI_X509_NAME *) data; ret = X509_set_issuer_name( xVal, aName ); break; case PKI_X509_DATA_NOTBEFORE: aTime = (PKI_TIME *) data; ret = X509_set_notBefore( xVal, aTime ); break; case PKI_X509_DATA_NOTAFTER: aTime = (PKI_TIME *) data; ret = X509_set_notAfter( xVal, aTime ); break; case PKI_X509_DATA_KEYPAIR_VALUE: aKey = data; ret = X509_set_pubkey( xVal, aKey); break; case PKI_X509_DATA_ALGORITHM: case PKI_X509_DATA_SIGNATURE_ALG1: alg = data; #if OPENSSL_VERSION_NUMBER < 0x1010000fL if (xVal->cert_info != NULL) xVal->cert_info->signature = alg; #else // Transfer Ownership xVal->cert_info.signature.algorithm = alg->algorithm; xVal->cert_info.signature.parameter = alg->parameter; // Remove the transfered data alg->algorithm = NULL; alg->parameter = NULL; // Free memory X509_ALGOR_free((X509_ALGOR *)data); data = NULL; #endif // Ok ret = 1; break; case PKI_X509_DATA_SIGNATURE_ALG2: // if (xVal->sig_alg != NULL ) X509_ALGOR_free(xVal->sig_alg); alg = data; #if OPENSSL_VERSION_NUMBER < 0x1010000fL xVal->sig_alg = alg; #else // Transfer Ownership xVal->sig_alg.algorithm = alg->algorithm; xVal->sig_alg.parameter = alg->parameter; // Remove the transfered data alg->algorithm = NULL; alg->parameter = NULL; // Free memory X509_ALGOR_free((X509_ALGOR *)alg); data = NULL; // Ok ret = 1; #endif break; default: /* Not Recognized/Supported DATATYPE */ ret = 0; break; } if (!ret) return PKI_ERR; return PKI_OK; }
int MAIN(int argc, char **argv) { ENGINE *e = NULL; int ret=1; X509_REQ *req=NULL; X509 *x=NULL,*xca=NULL; ASN1_OBJECT *objtmp; STACK_OF(OPENSSL_STRING) *sigopts = NULL; EVP_PKEY *Upkey=NULL,*CApkey=NULL; ASN1_INTEGER *sno = NULL; int i,num,badops=0; BIO *out=NULL; BIO *STDout=NULL; STACK_OF(ASN1_OBJECT) *trust = NULL, *reject = NULL; int informat,outformat,keyformat,CAformat,CAkeyformat; char *infile=NULL,*outfile=NULL,*keyfile=NULL,*CAfile=NULL; char *CAkeyfile=NULL,*CAserial=NULL; char *alias=NULL; int text=0,serial=0,subject=0,issuer=0,startdate=0,enddate=0; int next_serial=0; int subject_hash=0,issuer_hash=0,ocspid=0; #ifndef OPENSSL_NO_MD5 int subject_hash_old=0,issuer_hash_old=0; #endif int noout=0,sign_flag=0,CA_flag=0,CA_createserial=0,email=0; int ocsp_uri=0; int trustout=0,clrtrust=0,clrreject=0,aliasout=0,clrext=0; int C=0; int x509req=0,days=DEF_DAYS,modulus=0,pubkey=0; int pprint = 0; const char **pp; X509_STORE *ctx=NULL; X509_REQ *rq=NULL; int fingerprint=0; char buf[256]; const EVP_MD *md_alg,*digest=NULL; CONF *extconf = NULL; char *extsect = NULL, *extfile = NULL, *passin = NULL, *passargin = NULL; int need_rand = 0; int checkend=0,checkoffset=0; unsigned long nmflag = 0, certflag = 0; #ifndef OPENSSL_NO_ENGINE char *engine=NULL; #endif reqfile=0; apps_startup(); if (bio_err == NULL) bio_err=BIO_new_fp(stderr,BIO_NOCLOSE); if (!load_config(bio_err, NULL)) goto end; STDout=BIO_new_fp(stdout,BIO_NOCLOSE); #ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); STDout = BIO_push(tmpbio, STDout); } #endif informat=FORMAT_PEM; outformat=FORMAT_PEM; keyformat=FORMAT_PEM; CAformat=FORMAT_PEM; CAkeyformat=FORMAT_PEM; ctx=X509_STORE_new(); if (ctx == NULL) goto end; X509_STORE_set_verify_cb(ctx,callb); argc--; argv++; num=0; while (argc >= 1) { if (strcmp(*argv,"-inform") == 0) { if (--argc < 1) goto bad; informat=str2fmt(*(++argv)); } else if (strcmp(*argv,"-outform") == 0) { if (--argc < 1) goto bad; outformat=str2fmt(*(++argv)); } else if (strcmp(*argv,"-keyform") == 0) { if (--argc < 1) goto bad; keyformat=str2fmt(*(++argv)); } else if (strcmp(*argv,"-req") == 0) { reqfile=1; need_rand = 1; } else if (strcmp(*argv,"-CAform") == 0) { if (--argc < 1) goto bad; CAformat=str2fmt(*(++argv)); } else if (strcmp(*argv,"-CAkeyform") == 0) { if (--argc < 1) goto bad; CAkeyformat=str2fmt(*(++argv)); } else if (strcmp(*argv,"-sigopt") == 0) { if (--argc < 1) goto bad; if (!sigopts) sigopts = sk_OPENSSL_STRING_new_null(); if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv))) goto bad; } else if (strcmp(*argv,"-days") == 0) { if (--argc < 1) goto bad; days=atoi(*(++argv)); if (days == 0) { BIO_printf(STDout,"bad number of days\n"); goto bad; } } else if (strcmp(*argv,"-passin") == 0) { if (--argc < 1) goto bad; passargin= *(++argv); } else if (strcmp(*argv,"-extfile") == 0) { if (--argc < 1) goto bad; extfile= *(++argv); } else if (strcmp(*argv,"-extensions") == 0) { if (--argc < 1) goto bad; extsect= *(++argv); } else if (strcmp(*argv,"-in") == 0) { if (--argc < 1) goto bad; infile= *(++argv); } else if (strcmp(*argv,"-out") == 0) { if (--argc < 1) goto bad; outfile= *(++argv); } else if (strcmp(*argv,"-signkey") == 0) { if (--argc < 1) goto bad; keyfile= *(++argv); sign_flag= ++num; need_rand = 1; } else if (strcmp(*argv,"-CA") == 0) { if (--argc < 1) goto bad; CAfile= *(++argv); CA_flag= ++num; need_rand = 1; } else if (strcmp(*argv,"-CAkey") == 0) { if (--argc < 1) goto bad; CAkeyfile= *(++argv); } else if (strcmp(*argv,"-CAserial") == 0) { if (--argc < 1) goto bad; CAserial= *(++argv); } else if (strcmp(*argv,"-set_serial") == 0) { if (--argc < 1) goto bad; if (!(sno = s2i_ASN1_INTEGER(NULL, *(++argv)))) goto bad; } else if (strcmp(*argv,"-addtrust") == 0) { if (--argc < 1) goto bad; if (!(objtmp = OBJ_txt2obj(*(++argv), 0))) { BIO_printf(bio_err, "Invalid trust object value %s\n", *argv); goto bad; } if (!trust) trust = sk_ASN1_OBJECT_new_null(); sk_ASN1_OBJECT_push(trust, objtmp); trustout = 1; } else if (strcmp(*argv,"-addreject") == 0) { if (--argc < 1) goto bad; if (!(objtmp = OBJ_txt2obj(*(++argv), 0))) { BIO_printf(bio_err, "Invalid reject object value %s\n", *argv); goto bad; } if (!reject) reject = sk_ASN1_OBJECT_new_null(); sk_ASN1_OBJECT_push(reject, objtmp); trustout = 1; } else if (strcmp(*argv,"-setalias") == 0) { if (--argc < 1) goto bad; alias= *(++argv); trustout = 1; } else if (strcmp(*argv,"-certopt") == 0) { if (--argc < 1) goto bad; if (!set_cert_ex(&certflag, *(++argv))) goto bad; } else if (strcmp(*argv,"-nameopt") == 0) { if (--argc < 1) goto bad; if (!set_name_ex(&nmflag, *(++argv))) goto bad; } #ifndef OPENSSL_NO_ENGINE else if (strcmp(*argv,"-engine") == 0) { if (--argc < 1) goto bad; engine= *(++argv); } #endif else if (strcmp(*argv,"-C") == 0) C= ++num; else if (strcmp(*argv,"-email") == 0) email= ++num; else if (strcmp(*argv,"-ocsp_uri") == 0) ocsp_uri= ++num; else if (strcmp(*argv,"-serial") == 0) serial= ++num; else if (strcmp(*argv,"-next_serial") == 0) next_serial= ++num; else if (strcmp(*argv,"-modulus") == 0) modulus= ++num; else if (strcmp(*argv,"-pubkey") == 0) pubkey= ++num; else if (strcmp(*argv,"-x509toreq") == 0) x509req= ++num; else if (strcmp(*argv,"-text") == 0) text= ++num; else if (strcmp(*argv,"-hash") == 0 || strcmp(*argv,"-subject_hash") == 0) subject_hash= ++num; #ifndef OPENSSL_NO_MD5 else if (strcmp(*argv,"-subject_hash_old") == 0) subject_hash_old= ++num; #endif else if (strcmp(*argv,"-issuer_hash") == 0) issuer_hash= ++num; #ifndef OPENSSL_NO_MD5 else if (strcmp(*argv,"-issuer_hash_old") == 0) issuer_hash_old= ++num; #endif else if (strcmp(*argv,"-subject") == 0) subject= ++num; else if (strcmp(*argv,"-issuer") == 0) issuer= ++num; else if (strcmp(*argv,"-fingerprint") == 0) fingerprint= ++num; else if (strcmp(*argv,"-dates") == 0) { startdate= ++num; enddate= ++num; } else if (strcmp(*argv,"-purpose") == 0) pprint= ++num; else if (strcmp(*argv,"-startdate") == 0) startdate= ++num; else if (strcmp(*argv,"-enddate") == 0) enddate= ++num; else if (strcmp(*argv,"-checkend") == 0) { if (--argc < 1) goto bad; checkoffset=atoi(*(++argv)); checkend=1; } else if (strcmp(*argv,"-noout") == 0) noout= ++num; else if (strcmp(*argv,"-trustout") == 0) trustout= 1; else if (strcmp(*argv,"-clrtrust") == 0) clrtrust= ++num; else if (strcmp(*argv,"-clrreject") == 0) clrreject= ++num; else if (strcmp(*argv,"-alias") == 0) aliasout= ++num; else if (strcmp(*argv,"-CAcreateserial") == 0) CA_createserial= ++num; else if (strcmp(*argv,"-clrext") == 0) clrext = 1; #if 1 /* stay backwards-compatible with 0.9.5; this should go away soon */ else if (strcmp(*argv,"-crlext") == 0) { BIO_printf(bio_err,"use -clrext instead of -crlext\n"); clrext = 1; } #endif else if (strcmp(*argv,"-ocspid") == 0) ocspid= ++num; else if ((md_alg=EVP_get_digestbyname(*argv + 1))) { /* ok */ digest=md_alg; } else { BIO_printf(bio_err,"unknown option %s\n",*argv); badops=1; break; } argc--; argv++; } if (badops) { bad: for (pp=x509_usage; (*pp != NULL); pp++) BIO_printf(bio_err,"%s",*pp); goto end; } #ifndef OPENSSL_NO_ENGINE e = setup_engine(bio_err, engine, 0); #endif if (need_rand) app_RAND_load_file(NULL, bio_err, 0); ERR_load_crypto_strings(); if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } if (!X509_STORE_set_default_paths(ctx)) { ERR_print_errors(bio_err); goto end; } if ((CAkeyfile == NULL) && (CA_flag) && (CAformat == FORMAT_PEM)) { CAkeyfile=CAfile; } else if ((CA_flag) && (CAkeyfile == NULL)) { BIO_printf(bio_err,"need to specify a CAkey if using the CA command\n"); goto end; } if (extfile) { long errorline = -1; X509V3_CTX ctx2; extconf = NCONF_new(NULL); if (!NCONF_load(extconf, extfile,&errorline)) { if (errorline <= 0) BIO_printf(bio_err, "error loading the config file '%s'\n", extfile); else BIO_printf(bio_err, "error on line %ld of config file '%s'\n" ,errorline,extfile); goto end; } if (!extsect) { extsect = NCONF_get_string(extconf, "default", "extensions"); if (!extsect) { ERR_clear_error(); extsect = "default"; } } X509V3_set_ctx_test(&ctx2); X509V3_set_nconf(&ctx2, extconf); if (!X509V3_EXT_add_nconf(extconf, &ctx2, extsect, NULL)) { BIO_printf(bio_err, "Error Loading extension section %s\n", extsect); ERR_print_errors(bio_err); goto end; } } if (reqfile) { EVP_PKEY *pkey; BIO *in; if (!sign_flag && !CA_flag) { BIO_printf(bio_err,"We need a private key to sign with\n"); goto end; } in=BIO_new(BIO_s_file()); if (in == NULL) { ERR_print_errors(bio_err); goto end; } if (infile == NULL) BIO_set_fp(in,stdin,BIO_NOCLOSE|BIO_FP_TEXT); else { if (BIO_read_filename(in,infile) <= 0) { perror(infile); BIO_free(in); goto end; } } req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL); BIO_free(in); if (req == NULL) { ERR_print_errors(bio_err); goto end; } if ( (req->req_info == NULL) || (req->req_info->pubkey == NULL) || (req->req_info->pubkey->public_key == NULL) || (req->req_info->pubkey->public_key->data == NULL)) { BIO_printf(bio_err,"The certificate request appears to corrupted\n"); BIO_printf(bio_err,"It does not contain a public key\n"); goto end; } if ((pkey=X509_REQ_get_pubkey(req)) == NULL) { BIO_printf(bio_err,"error unpacking public key\n"); goto end; } i=X509_REQ_verify(req,pkey); EVP_PKEY_free(pkey); if (i < 0) { BIO_printf(bio_err,"Signature verification error\n"); ERR_print_errors(bio_err); goto end; } if (i == 0) { BIO_printf(bio_err,"Signature did not match the certificate request\n"); goto end; } else BIO_printf(bio_err,"Signature ok\n"); print_name(bio_err, "subject=", X509_REQ_get_subject_name(req), nmflag); if ((x=X509_new()) == NULL) goto end; if (sno == NULL) { sno = ASN1_INTEGER_new(); if (!sno || !rand_serial(NULL, sno)) goto end; if (!X509_set_serialNumber(x, sno)) goto end; ASN1_INTEGER_free(sno); sno = NULL; } else if (!X509_set_serialNumber(x, sno)) goto end; if (!X509_set_issuer_name(x,req->req_info->subject)) goto end; if (!X509_set_subject_name(x,req->req_info->subject)) goto end; X509_gmtime_adj(X509_get_notBefore(x),0); X509_time_adj_ex(X509_get_notAfter(x),days, 0, NULL); pkey = X509_REQ_get_pubkey(req); X509_set_pubkey(x,pkey); EVP_PKEY_free(pkey); } else x=load_cert(bio_err,infile,informat,NULL,e,"Certificate"); if (x == NULL) goto end; if (CA_flag) { xca=load_cert(bio_err,CAfile,CAformat,NULL,e,"CA Certificate"); if (xca == NULL) goto end; } if (!noout || text || next_serial) { OBJ_create("2.99999.3", "SET.ex3","SET x509v3 extension 3"); out=BIO_new(BIO_s_file()); if (out == NULL) { ERR_print_errors(bio_err); goto end; } if (outfile == NULL) { BIO_set_fp(out,stdout,BIO_NOCLOSE); #ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); out = BIO_push(tmpbio, out); } #endif } else { if (BIO_write_filename(out,outfile) <= 0) { perror(outfile); goto end; } } } if (alias) X509_alias_set1(x, (unsigned char *)alias, -1); if (clrtrust) X509_trust_clear(x); if (clrreject) X509_reject_clear(x); if (trust) { for (i = 0; i < sk_ASN1_OBJECT_num(trust); i++) { objtmp = sk_ASN1_OBJECT_value(trust, i); X509_add1_trust_object(x, objtmp); } } if (reject) { for (i = 0; i < sk_ASN1_OBJECT_num(reject); i++) { objtmp = sk_ASN1_OBJECT_value(reject, i); X509_add1_reject_object(x, objtmp); } } if (num) { for (i=1; i<=num; i++) { if (issuer == i) { print_name(STDout, "issuer= ", X509_get_issuer_name(x), nmflag); } else if (subject == i) { print_name(STDout, "subject= ", X509_get_subject_name(x), nmflag); } else if (serial == i) { BIO_printf(STDout,"serial="); i2a_ASN1_INTEGER(STDout, X509_get_serialNumber(x)); BIO_printf(STDout,"\n"); } else if (next_serial == i) { BIGNUM *bnser; ASN1_INTEGER *ser; ser = X509_get_serialNumber(x); bnser = ASN1_INTEGER_to_BN(ser, NULL); if (!bnser) goto end; if (!BN_add_word(bnser, 1)) goto end; ser = BN_to_ASN1_INTEGER(bnser, NULL); if (!ser) goto end; BN_free(bnser); i2a_ASN1_INTEGER(out, ser); ASN1_INTEGER_free(ser); BIO_puts(out, "\n"); } else if ((email == i) || (ocsp_uri == i)) { int j; STACK_OF(OPENSSL_STRING) *emlst; if (email == i) emlst = X509_get1_email(x); else emlst = X509_get1_ocsp(x); for (j = 0; j < sk_OPENSSL_STRING_num(emlst); j++) BIO_printf(STDout, "%s\n", sk_OPENSSL_STRING_value(emlst, j)); X509_email_free(emlst); } else if (aliasout == i) { unsigned char *alstr; alstr = X509_alias_get0(x, NULL); if (alstr) BIO_printf(STDout,"%s\n", alstr); else BIO_puts(STDout,"<No Alias>\n"); } else if (subject_hash == i) { BIO_printf(STDout,"%08lx\n",X509_subject_name_hash(x)); } #ifndef OPENSSL_NO_MD5 else if (subject_hash_old == i) { BIO_printf(STDout,"%08lx\n",X509_subject_name_hash_old(x)); } #endif else if (issuer_hash == i) { BIO_printf(STDout,"%08lx\n",X509_issuer_name_hash(x)); } #ifndef OPENSSL_NO_MD5 else if (issuer_hash_old == i) { BIO_printf(STDout,"%08lx\n",X509_issuer_name_hash_old(x)); } #endif else if (pprint == i) { X509_PURPOSE *ptmp; int j; BIO_printf(STDout, "Certificate purposes:\n"); for (j = 0; j < X509_PURPOSE_get_count(); j++) { ptmp = X509_PURPOSE_get0(j); purpose_print(STDout, x, ptmp); } } else if (modulus == i) { EVP_PKEY *pkey; pkey=X509_get_pubkey(x); if (pkey == NULL) { BIO_printf(bio_err,"Modulus=unavailable\n"); ERR_print_errors(bio_err); goto end; } BIO_printf(STDout,"Modulus="); #ifndef OPENSSL_NO_RSA if (pkey->type == EVP_PKEY_RSA) BN_print(STDout,pkey->pkey.rsa->n); else #endif #ifndef OPENSSL_NO_DSA if (pkey->type == EVP_PKEY_DSA) BN_print(STDout,pkey->pkey.dsa->pub_key); else #endif BIO_printf(STDout,"Wrong Algorithm type"); BIO_printf(STDout,"\n"); EVP_PKEY_free(pkey); } else if (pubkey == i) { EVP_PKEY *pkey; pkey=X509_get_pubkey(x); if (pkey == NULL) { BIO_printf(bio_err,"Error getting public key\n"); ERR_print_errors(bio_err); goto end; } PEM_write_bio_PUBKEY(STDout, pkey); EVP_PKEY_free(pkey); } else if (C == i) { unsigned char *d; char *m; int y,z; X509_NAME_oneline(X509_get_subject_name(x), buf,sizeof buf); BIO_printf(STDout,"/* subject:%s */\n",buf); m=X509_NAME_oneline( X509_get_issuer_name(x),buf, sizeof buf); BIO_printf(STDout,"/* issuer :%s */\n",buf); z=i2d_X509(x,NULL); m=OPENSSL_malloc(z); d=(unsigned char *)m; z=i2d_X509_NAME(X509_get_subject_name(x),&d); BIO_printf(STDout,"unsigned char XXX_subject_name[%d]={\n",z); d=(unsigned char *)m; for (y=0; y<z; y++) { BIO_printf(STDout,"0x%02X,",d[y]); if ((y & 0x0f) == 0x0f) BIO_printf(STDout,"\n"); } if (y%16 != 0) BIO_printf(STDout,"\n"); BIO_printf(STDout,"};\n"); z=i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x),&d); BIO_printf(STDout,"unsigned char XXX_public_key[%d]={\n",z); d=(unsigned char *)m; for (y=0; y<z; y++) { BIO_printf(STDout,"0x%02X,",d[y]); if ((y & 0x0f) == 0x0f) BIO_printf(STDout,"\n"); } if (y%16 != 0) BIO_printf(STDout,"\n"); BIO_printf(STDout,"};\n"); z=i2d_X509(x,&d); BIO_printf(STDout,"unsigned char XXX_certificate[%d]={\n",z); d=(unsigned char *)m; for (y=0; y<z; y++) { BIO_printf(STDout,"0x%02X,",d[y]); if ((y & 0x0f) == 0x0f) BIO_printf(STDout,"\n"); } if (y%16 != 0) BIO_printf(STDout,"\n"); BIO_printf(STDout,"};\n"); OPENSSL_free(m); } else if (text == i) { X509_print_ex(out,x,nmflag, certflag); } else if (startdate == i) { BIO_puts(STDout,"notBefore="); ASN1_TIME_print(STDout,X509_get_notBefore(x)); BIO_puts(STDout,"\n"); } else if (enddate == i) { BIO_puts(STDout,"notAfter="); ASN1_TIME_print(STDout,X509_get_notAfter(x)); BIO_puts(STDout,"\n"); } else if (fingerprint == i) { int j; unsigned int n; unsigned char md[EVP_MAX_MD_SIZE]; const EVP_MD *fdig = digest; if (!fdig) fdig = EVP_sha1(); if (!X509_digest(x,fdig,md,&n)) { BIO_printf(bio_err,"out of memory\n"); goto end; } BIO_printf(STDout,"%s Fingerprint=", OBJ_nid2sn(EVP_MD_type(fdig))); for (j=0; j<(int)n; j++) { BIO_printf(STDout,"%02X%c",md[j], (j+1 == (int)n) ?'\n':':'); } } /* should be in the library */ else if ((sign_flag == i) && (x509req == 0)) { BIO_printf(bio_err,"Getting Private key\n"); if (Upkey == NULL) { Upkey=load_key(bio_err, keyfile, keyformat, 0, passin, e, "Private key"); if (Upkey == NULL) goto end; } assert(need_rand); if (!sign(x,Upkey,days,clrext,digest, extconf, extsect)) goto end; } else if (CA_flag == i) { BIO_printf(bio_err,"Getting CA Private Key\n"); if (CAkeyfile != NULL) { CApkey=load_key(bio_err, CAkeyfile, CAkeyformat, 0, passin, e, "CA Private Key"); if (CApkey == NULL) goto end; } assert(need_rand); if (!x509_certify(ctx,CAfile,digest,x,xca, CApkey, sigopts, CAserial,CA_createserial,days, clrext, extconf, extsect, sno)) goto end; } else if (x509req == i) { EVP_PKEY *pk; BIO_printf(bio_err,"Getting request Private Key\n"); if (keyfile == NULL) { BIO_printf(bio_err,"no request key file specified\n"); goto end; } else { pk=load_key(bio_err, keyfile, keyformat, 0, passin, e, "request key"); if (pk == NULL) goto end; } BIO_printf(bio_err,"Generating certificate request\n"); rq=X509_to_X509_REQ(x,pk,digest); EVP_PKEY_free(pk); if (rq == NULL) { ERR_print_errors(bio_err); goto end; } if (!noout) { X509_REQ_print(out,rq); PEM_write_bio_X509_REQ(out,rq); } noout=1; } else if (ocspid == i) { X509_ocspid_print(out, x); } } } if (checkend) { time_t tcheck=time(NULL) + checkoffset; if (X509_cmp_time(X509_get_notAfter(x), &tcheck) < 0) { BIO_printf(out,"Certificate will expire\n"); ret=1; } else { BIO_printf(out,"Certificate will not expire\n"); ret=0; } goto end; } if (noout) { ret=0; goto end; } if (outformat == FORMAT_ASN1) i=i2d_X509_bio(out,x); else if (outformat == FORMAT_PEM) { if (trustout) i=PEM_write_bio_X509_AUX(out,x); else i=PEM_write_bio_X509(out,x); } else if (outformat == FORMAT_NETSCAPE) { NETSCAPE_X509 nx; ASN1_OCTET_STRING hdr; hdr.data=(unsigned char *)NETSCAPE_CERT_HDR; hdr.length=strlen(NETSCAPE_CERT_HDR); nx.header= &hdr; nx.cert=x; i=ASN1_item_i2d_bio(ASN1_ITEM_rptr(NETSCAPE_X509),out,&nx); } else { BIO_printf(bio_err,"bad output format specified for outfile\n"); goto end; } if (!i) { BIO_printf(bio_err,"unable to write certificate\n"); ERR_print_errors(bio_err); goto end; } ret=0; end: if (need_rand) app_RAND_write_file(NULL, bio_err); OBJ_cleanup(); NCONF_free(extconf); BIO_free_all(out); BIO_free_all(STDout); X509_STORE_free(ctx); X509_REQ_free(req); X509_free(x); X509_free(xca); EVP_PKEY_free(Upkey); EVP_PKEY_free(CApkey); if (sigopts) sk_OPENSSL_STRING_free(sigopts); X509_REQ_free(rq); ASN1_INTEGER_free(sno); sk_ASN1_OBJECT_pop_free(trust, ASN1_OBJECT_free); sk_ASN1_OBJECT_pop_free(reject, ASN1_OBJECT_free); if (passin) OPENSSL_free(passin); apps_shutdown(); OPENSSL_EXIT(ret); }
KSSLCertificate* KSSLCertificateFactory::generateSelfSigned(KSSLKeyType /*keytype*/) { #if 0 //#ifdef KSSL_HAVE_SSL X509_NAME *x509name = X509_NAME_new(); X509 *x509; ASN1_UTCTIME *beforeafter; KSSLCertificate *newcert; int rc; // FIXME: generate the private key if (keytype == KEYTYPE_UNKNOWN || (key=EVP_PKEY_new()) == NULL) { X509_NAME_free(x509name); return NULL; } switch(keytype) { case KEYTYPE_RSA: if (!EVP_PKEY_assign_RSA(key, RSA_generate_key(newkey,0x10001, req_cb,bio_err))) { } break; case KEYTYPE_DSA: if (!DSA_generate_key(dsa_params)) goto end; if (!EVP_PKEY_assign_DSA(pkey,dsa_params)) goto end; dsa_params=NULL; if (pkey->type == EVP_PKEY_DSA) digest=EVP_dss1(); break; } // FIXME: dn doesn't exist // FIXME: allow the notAfter value to be parameterized // FIXME: allow a password to lock the key with // Fill in the certificate X509_NAME_add_entry_by_NID(x509name, OBJ_txt2nid("CN"), 0x1001, (unsigned char *) dn, -1, -1, 0); x509 = X509_new(); rc = X509_set_issuer_name(x509, x509name); if (rc != 0) { X509_free(x509); X509_NAME_free(x509name); return NULL; } rc = X509_set_subject_name(x509, x509name); if (rc != 0) { X509_free(x509); X509_NAME_free(x509name); return NULL; } ASN1_INTEGER_set(X509_get_serialNumber(*x509), 0); X509_NAME_free(x509name); // Make it a 1 year certificate beforeafter = ASN1_UTCTIME_new(); if (!X509_gmtime_adj(beforeafter, -60*60*24)) { // yesterday X509_free(x509); return NULL; } if (!X509_set_notBefore(x509, beforeafter)) { X509_free(x509); return NULL; } if (!X509_gmtime_adj(beforeafter, 60*60*24*364)) { // a year from yesterday X509_free(x509); return NULL; } if (!X509_set_notAfter(x509, beforeafter)) { X509_free(x509); return NULL; } ASN1_UTCTIME_free(beforeafter); if (!X509_set_pubkey(x509, key)) { X509_free(x509); return NULL; } rc = X509_sign(x509, key, EVP_sha1()); if (rc != 0) { X509_free(x509); return NULL; } newCert = new KSSLCertificate; newCert->setCert(x509); return newCert; #else return NULL; #endif }