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) { X509err (X509_F_X509_REQ_TO_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 STACK_OF(X509_NAME) * tlso_ca_list( char * bundle, char * dir, X509 *cert ) { STACK_OF(X509_NAME) *ca_list = NULL; if ( bundle ) { ca_list = SSL_load_client_CA_file( bundle ); } #if defined(HAVE_DIRENT_H) || defined(dirent) if ( dir ) { int freeit = 0; if ( !ca_list ) { ca_list = sk_X509_NAME_new_null(); freeit = 1; } if ( !SSL_add_dir_cert_subjects_to_stack( ca_list, dir ) && freeit ) { sk_X509_NAME_free( ca_list ); ca_list = NULL; } } #endif if ( cert ) { X509_NAME *xn = X509_get_subject_name( cert ); xn = X509_NAME_dup( xn ); if ( !ca_list ) ca_list = sk_X509_NAME_new_null(); if ( xn && ca_list ) sk_X509_NAME_push( ca_list, xn ); } return ca_list; }
static int openssl_xname_dup(lua_State*L) { X509_NAME* xn = CHECK_OBJECT(1, X509_NAME, "openssl.x509_name"); X509_NAME* dup = X509_NAME_dup(xn); PUSH_OBJECT(dup, "openssl.x509_name"); return 1; };
static STACK_OF(X509_NAME) * use_inline_load_client_CA_file (SSL_CTX *ctx, const char *ca_string) { BIO *in = NULL; X509 *x = NULL; X509_NAME *xn = NULL; STACK_OF(X509_NAME) *ret = NULL, *sk; sk=sk_X509_NAME_new(xname_cmp); in = BIO_new_mem_buf ((char *)ca_string, -1); if (!in) goto err; if ((sk == NULL) || (in == NULL)) goto err; for (;;) { if (PEM_read_bio_X509(in,&x,NULL,NULL) == NULL) break; if (ret == NULL) { ret = sk_X509_NAME_new_null(); if (ret == NULL) goto err; } if ((xn=X509_get_subject_name(x)) == NULL) goto err; /* check for duplicates */ xn=X509_NAME_dup(xn); if (xn == NULL) goto err; if (sk_X509_NAME_find(sk,xn) >= 0) X509_NAME_free(xn); else { sk_X509_NAME_push(sk,xn); sk_X509_NAME_push(ret,xn); } } if (0) { err: if (ret != NULL) sk_X509_NAME_pop_free(ret,X509_NAME_free); ret=NULL; } if (sk != NULL) sk_X509_NAME_free(sk); if (in != NULL) BIO_free(in); if (x != NULL) X509_free(x); if (ret != NULL) ERR_clear_error(); return(ret); }
MONO_API MonoBtlsX509Name * mono_btls_x509_name_copy (X509_NAME *xn) { MonoBtlsX509Name *name; name = OPENSSL_malloc (sizeof (MonoBtlsX509Name)); if (!name) return NULL; memset(name, 0, sizeof(MonoBtlsX509Name)); name->name = X509_NAME_dup(xn); name->owns = 1; return name; }
PKCS7_ISSUER_AND_SERIAL *X509_get_ISSUER_AND_SERIAL( X509 *cert ) { PKCS7_ISSUER_AND_SERIAL *ias = NULL; if(!cert) return NULL; if((ias = PKCS7_ISSUER_AND_SERIAL_new()) == NULL ) return NULL; ias->issuer = X509_NAME_dup( X509_get_issuer_name(cert)); ias->serial = ASN1_INTEGER_dup( X509_get_serialNumber(cert) ); return ias; }
int X509_NAME_set(X509_NAME **xn, X509_NAME *name) { X509_NAME *in; if (*xn == NULL) return(0); if (*xn != name) { in=X509_NAME_dup(name); if (in != NULL) { X509_NAME_free(*xn); *xn=in; } } return(*xn != NULL); }
int STORE_ATTR_INFO_set_dn(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code, X509_NAME *dn) { if (!attrs) { STOREerr(STORE_F_STORE_ATTR_INFO_SET_DN, ERR_R_PASSED_NULL_PARAMETER); return 0; } if (!ATTR_IS_SET(attrs, code)) { if ((attrs->values[code].dn = X509_NAME_dup(dn))) return 1; STOREerr(STORE_F_STORE_ATTR_INFO_SET_DN, ERR_R_MALLOC_FAILURE); return 0; } STOREerr(STORE_F_STORE_ATTR_INFO_SET_DN, STORE_R_ALREADY_HAS_A_VALUE); return 0; }
static PyObject * ssl_Connection_get_client_ca_list(ssl_ConnectionObj *self, PyObject *args) { STACK_OF(X509_NAME) *CANames; PyObject *CAList; int i, n; if (!PyArg_ParseTuple(args, ":get_client_ca_list")) { return NULL; } CANames = SSL_get_client_CA_list(self->ssl); if (CANames == NULL) { return PyList_New(0); } n = sk_X509_NAME_num(CANames); CAList = PyList_New(n); if (CAList == NULL) { return NULL; } for (i = 0; i < n; i++) { X509_NAME *CAName; PyObject *CA; CAName = X509_NAME_dup(sk_X509_NAME_value(CANames, i)); if (CAName == NULL) { Py_DECREF(CAList); exception_from_error_queue(ssl_Error); return NULL; } CA = (PyObject *)new_x509name(CAName, 1); if (CA == NULL) { X509_NAME_free(CAName); Py_DECREF(CAList); return NULL; } if (PyList_SetItem(CAList, i, CA)) { Py_DECREF(CA); Py_DECREF(CAList); return NULL; } } return CAList; }
static int openssl_push_pkcs7_signer_info(lua_State *L, PKCS7_SIGNER_INFO *info) { lua_newtable(L); AUXILIAR_SET(L, -1, "version", ASN1_INTEGER_get(info->version), integer); if (info->issuer_and_serial != NULL) { X509_NAME *i = X509_NAME_dup(info->issuer_and_serial->issuer); ASN1_INTEGER *s = ASN1_INTEGER_dup(info->issuer_and_serial->serial); if (info->issuer_and_serial->issuer) AUXILIAR_SETOBJECT(L, i, "openssl.x509_name", -1, "issuer"); if (info->issuer_and_serial->serial) AUXILIAR_SETOBJECT(L, s, "openssl.asn1_integer", -1, "serial"); } if (info->digest_alg) { X509_ALGOR *dup = X509_ALGOR_dup(info->digest_alg); AUXILIAR_SETOBJECT(L, dup, "openssl.x509_algor", -1, "digest_alg"); } if (info->digest_enc_alg) { X509_ALGOR *dup = X509_ALGOR_dup(info->digest_alg); AUXILIAR_SETOBJECT(L, dup, "openssl.x509_algor", -1, "digest_enc_alg"); } if (info->enc_digest) { ASN1_STRING *dup = ASN1_STRING_dup(info->enc_digest); AUXILIAR_SETOBJECT(L, dup, "openssl.asn1_string", -1, "enc_digest"); } if (info->pkey) { CRYPTO_add(&info->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); AUXILIAR_SETOBJECT(L, info->pkey, "openssl.evp_pkey", -1, "pkey"); } return 1; }
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; }
void tls_ctx_load_ca (struct tls_root_ctx *ctx, const char *ca_file, const char *ca_file_inline, const char *ca_path, bool tls_server ) { STACK_OF(X509_INFO) *info_stack = NULL; STACK_OF(X509_NAME) *cert_names = NULL; X509_LOOKUP *lookup = NULL; X509_STORE *store = NULL; X509_NAME *xn = NULL; BIO *in = NULL; int i, added = 0; ASSERT(NULL != ctx); store = SSL_CTX_get_cert_store(ctx->ctx); if (!store) msg(M_SSLERR, "Cannot get certificate store (SSL_CTX_get_cert_store)"); /* Try to add certificates and CRLs from ca_file */ if (ca_file) { if (!strcmp (ca_file, INLINE_FILE_TAG) && ca_file_inline) in = BIO_new_mem_buf ((char *)ca_file_inline, -1); else in = BIO_new_file (ca_file, "r"); if (in) info_stack = PEM_X509_INFO_read_bio (in, NULL, NULL, NULL); if (info_stack) { for (i = 0; i < sk_X509_INFO_num (info_stack); i++) { X509_INFO *info = sk_X509_INFO_value (info_stack, i); if (info->crl) X509_STORE_add_crl (store, info->crl); if (info->x509) { X509_STORE_add_cert (store, info->x509); added++; if (!tls_server) continue; /* Use names of CAs as a client CA list */ if (cert_names == NULL) { cert_names = sk_X509_NAME_new (sk_x509_name_cmp); if (!cert_names) continue; } xn = X509_get_subject_name (info->x509); if (!xn) continue; /* Don't add duplicate CA names */ if (sk_X509_NAME_find (cert_names, xn) == -1) { xn = X509_NAME_dup (xn); if (!xn) continue; sk_X509_NAME_push (cert_names, xn); } } } sk_X509_INFO_pop_free (info_stack, X509_INFO_free); } if (tls_server) SSL_CTX_set_client_CA_list (ctx->ctx, cert_names); if (!added || (tls_server && sk_X509_NAME_num (cert_names) != added)) msg (M_SSLERR, "Cannot load CA certificate file %s", np(ca_file)); if (in) BIO_free (in); } /* Set a store for certs (CA & CRL) with a lookup on the "capath" hash directory */ if (ca_path) { lookup = X509_STORE_add_lookup (store, X509_LOOKUP_hash_dir ()); if (lookup && X509_LOOKUP_add_dir (lookup, ca_path, X509_FILETYPE_PEM)) msg(M_WARN, "WARNING: experimental option --capath %s", ca_path); else msg(M_SSLERR, "Cannot add lookup at --capath %s", ca_path); #if OPENSSL_VERSION_NUMBER >= 0x00907000L X509_STORE_set_flags (store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); #else msg(M_WARN, "WARNING: this version of OpenSSL cannot handle CRL files in capath"); #endif } }
/* Load CA certs from a file into a STACK. Note that it is somewhat misnamed; * it doesn't really have anything to do with clients (except that a common use * for a stack of CAs is to send it to the client). Actually, it doesn't have * much to do with CAs, either, since it will load any old cert. * * \param file the file containing one or more certs. * \return a ::STACK containing the certs. */ STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file) { BIO *in; X509 *x = NULL; X509_NAME *xn = NULL; STACK_OF(X509_NAME) *ret = NULL, *sk; sk = sk_X509_NAME_new(xname_cmp); in = BIO_new(BIO_s_file()); if (sk == NULL || in == NULL) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } if (!BIO_read_filename(in, file)) { goto err; } for (;;) { if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) { break; } if (ret == NULL) { ret = sk_X509_NAME_new_null(); if (ret == NULL) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } } xn = X509_get_subject_name(x); if (xn == NULL) { goto err; } /* check for duplicates */ xn = X509_NAME_dup(xn); if (xn == NULL) { goto err; } if (sk_X509_NAME_find(sk, NULL, xn)) { X509_NAME_free(xn); } else { sk_X509_NAME_push(sk, xn); sk_X509_NAME_push(ret, xn); } } if (0) { err: sk_X509_NAME_pop_free(ret, X509_NAME_free); ret = NULL; } sk_X509_NAME_free(sk); BIO_free(in); X509_free(x); if (ret != NULL) { ERR_clear_error(); } return ret; }
int openssl_push_xname_asobject(lua_State*L, X509_NAME* xname) { X509_NAME* dup = X509_NAME_dup(xname); PUSH_OBJECT(dup, "openssl.x509_name"); return 1; }
int openssl_xext_totable(lua_State* L, X509_EXTENSION *x, int utf8) { lua_newtable(L); openssl_push_asn1object(L, x->object); lua_setfield(L, -2, "object"); PUSH_ASN1_OCTET_STRING(L, x->value); lua_setfield(L,-2, "value"); AUXILIAR_SET(L, -1, "critical", x->critical, boolean); switch (x->object->nid) { case NID_subject_alt_name: { int i; int n_general_names; STACK_OF(GENERAL_NAME) *values = X509V3_EXT_d2i(x); if (values == NULL) break; /* Push ret[oid] */ openssl_push_asn1object(L, x->object); lua_newtable(L); n_general_names = sk_GENERAL_NAME_num(values); for (i = 0; i < n_general_names; i++) { GENERAL_NAME *general_name = sk_GENERAL_NAME_value(values, i); switch (general_name->type) { case GEN_OTHERNAME: { OTHERNAME *otherName = general_name->d.otherName; lua_newtable(L); openssl_push_asn1object(L, otherName->type_id); PUSH_ASN1_STRING(L, otherName->value->value.asn1_string, utf8); lua_settable(L, -3); lua_setfield(L, -2, "otherName"); lua_pushstring(L, "otherName"); lua_rawseti(L, -2, i+1); break; } case GEN_EMAIL: lua_newtable(L); PUSH_ASN1_STRING(L, general_name->d.rfc822Name, utf8); lua_pushstring(L, "rfc822Name"); lua_settable(L, -3); lua_pushstring(L, "rfc822Name"); lua_rawseti(L, -2, i+1); break; case GEN_DNS: lua_newtable(L); PUSH_ASN1_STRING(L, general_name->d.dNSName, utf8); lua_setfield(L, -2, "dNSName"); lua_pushstring(L, "dNSName"); lua_rawseti(L, -2, i+1); break; case GEN_X400: lua_newtable(L); openssl_push_asn1type(L, general_name->d.x400Address); lua_setfield(L, -2, "x400Address"); lua_pushstring(L, "x400Address"); lua_rawseti(L, -2, i+1); break; case GEN_DIRNAME: { X509_NAME* xn = general_name->d.directoryName; lua_newtable(L); PUSH_OBJECT(X509_NAME_dup(xn), "openssl.x509_name"); lua_setfield(L, -2, "directoryName"); lua_pushstring(L, "directoryName"); lua_rawseti(L, -2, i+1); } break; case GEN_URI: lua_newtable(L); PUSH_ASN1_STRING(L, general_name->d.uniformResourceIdentifier, utf8); lua_setfield(L, -2, "uniformResourceIdentifier"); lua_pushstring(L, "uniformResourceIdentifier"); lua_rawseti(L, -2, i+1); break; case GEN_IPADD: lua_newtable(L); PUSH_ASN1_OCTET_STRING(L, general_name->d.iPAddress); lua_setfield(L, -2, "iPAddress"); lua_pushstring(L, "iPAddress"); lua_rawseti(L, -2, i+1); break; case GEN_EDIPARTY: lua_newtable(L); lua_newtable(L); PUSH_ASN1_STRING(L, general_name->d.ediPartyName->nameAssigner,utf8); lua_setfield(L, -2, "nameAssigner"); PUSH_ASN1_STRING(L, general_name->d.ediPartyName->partyName,utf8); lua_setfield(L, -2, "partyName"); lua_setfield(L, -2, "ediPartyName"); lua_pushstring(L, "ediPartyName"); lua_rawseti(L, -2, i+1); break; case GEN_RID: lua_newtable(L); openssl_push_asn1object(L, general_name->d.registeredID); lua_setfield(L, -2, "registeredID"); lua_pushstring(L, "registeredID"); lua_rawseti(L, -2, i+1); break; } } lua_settable(L, -3); } default: break; } return 1; };
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 ); };
CPK_PUBLIC_PARAMS *CPK_MASTER_SECRET_extract_public_params(CPK_MASTER_SECRET *master) { CPK_PUBLIC_PARAMS *param = NULL; int pkey_type; pkey_type = OBJ_obj2nid(master->pkey_algor->algorithm); if (!(param = CPK_PUBLIC_PARAMS_new())) { CPKerr(CPK_F_CPK_MASTER_SECRET_EXTRACT_PUBLIC_PARAMS, ERR_R_MALLOC_FAILURE); goto err; } param->version = master->version; X509_NAME_free(param->id); if (!(param->id = X509_NAME_dup(master->id))) { CPKerr(CPK_F_CPK_MASTER_SECRET_EXTRACT_PUBLIC_PARAMS, ERR_R_MALLOC_FAILURE); goto err; } X509_ALGOR_free(param->pkey_algor); if (!(param->pkey_algor = X509_ALGOR_dup(master->pkey_algor))) { CPKerr(CPK_F_CPK_MASTER_SECRET_EXTRACT_PUBLIC_PARAMS, ERR_R_MALLOC_FAILURE); goto err; } X509_ALGOR_free(param->map_algor); if (!(param->map_algor = X509_ALGOR_dup(master->map_algor))) { CPKerr(CPK_F_CPK_MASTER_SECRET_EXTRACT_PUBLIC_PARAMS, ERR_R_MALLOC_FAILURE); goto err; } switch (pkey_type) { case EVP_PKEY_DSA: if (!extract_dsa_params(master, param)) { CPKerr(CPK_F_CPK_MASTER_SECRET_EXTRACT_PUBLIC_PARAMS, ERR_R_CPK_LIB); goto err; } break; case EVP_PKEY_EC: if (!extract_ec_params(master, param)) { CPKerr(CPK_F_CPK_MASTER_SECRET_EXTRACT_PUBLIC_PARAMS, ERR_R_CPK_LIB); goto err; } break; default: CPKerr(CPK_F_CPK_MASTER_SECRET_EXTRACT_PUBLIC_PARAMS, CPK_R_INVALID_PKEY_TYPE); goto err; } return param; err: if (param) CPK_PUBLIC_PARAMS_free(param); return NULL; }