static int openssl_xext_new_sk(lua_State* L) { size_t i; X509_EXTENSION *x=NULL; STACK_OF(X509_EXTENSION) *exts; int utf8 = lua_isnoneornil(L, 2) ? 1 : lua_toboolean(L, 2); luaL_checktable(L,1); exts = sk_X509_EXTENSION_new_null(); for (i=0; i<lua_objlen(L, 1); i++) { lua_rawgeti(L,1, i+1); x = openssl_new_xextension(L, NULL, -1, utf8); sk_X509_EXTENSION_push(exts, x); } PUSH_OBJECT(exts, "openssl.stack_of_x509_extension"); return 1; };
int X509V3_EXT_REQ_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section, X509_REQ *req) { X509_EXTENSION *ext; STACK_OF(X509_EXTENSION) *extlist = NULL; STACK_OF(CONF_VALUE) *nval; CONF_VALUE *val; int i; if(!(nval = CONF_get_section(conf, section))) return 0; for(i = 0; i < sk_CONF_VALUE_num(nval); i++) { val = sk_CONF_VALUE_value(nval, i); if(!(ext = X509V3_EXT_conf(conf, ctx, val->name, val->value))) return 0; if(!extlist) extlist = sk_X509_EXTENSION_new_null(); sk_X509_EXTENSION_push(extlist, ext); } if(req) i = X509_REQ_add_extensions(req, extlist); else i = 1; sk_X509_EXTENSION_pop_free(extlist, X509_EXTENSION_free); return i; }
static int openssl_xext_new_sk(lua_State* L) { size_t i; X509_EXTENSION *x = NULL; STACK_OF(X509_EXTENSION) *exts; int v3 = 1; luaL_checktable(L, 1); if (!lua_isnone(L, 2)) v3 = lua_toboolean(L, 2); exts = sk_X509_EXTENSION_new_null(); for (i = 0; i < lua_rawlen(L, 1); i++) { lua_rawgeti(L, 1, i + 1); x = openssl_new_xextension(L, lua_gettop(L), v3); if (x) sk_X509_EXTENSION_push(exts, x); } PUSH_OBJECT(exts, "openssl.stack_of_x509_extension"); return 1; };
int main(int argc, char *argv[]) { STACK_OF(X509_EXTENSION) * sk = NULL; X509_EXTENSION *hash_ext = NULL; X509_EXTENSION *nvctr_ext = NULL; X509_EXTENSION *trusted_key_ext = NULL; X509_EXTENSION *non_trusted_key_ext = NULL; FILE *file = NULL; int i, tz_nvctr_nid, ntz_nvctr_nid, hash_nid, pk_nid; int c, opt_idx = 0; unsigned int err_code; unsigned char md[SHA256_DIGEST_LENGTH]; const EVP_MD *md_info; NOTICE("CoT Generation Tool: %s\n", build_msg); NOTICE("Target platform: %s\n", platform_msg); /* Set default options */ key_alg = KEY_ALG_RSA; while (1) { /* getopt_long stores the option index here. */ c = getopt_long(argc, argv, "ahknp", long_opt, &opt_idx); /* Detect the end of the options. */ if (c == -1) { break; } switch (c) { case 'a': key_alg = get_key_alg(optarg); if (key_alg < 0) { ERROR("Invalid key algorithm '%s'\n", optarg); exit(1); } break; case 'h': print_help(argv[0]); break; case 'k': save_keys = 1; break; case 'n': new_keys = 1; break; case 'p': print_cert = 1; break; case BL2_ID: certs[BL2_CERT].bin = strdup(optarg); break; case BL30_ID: certs[BL30_CERT].bin = strdup(optarg); break; case BL31_ID: certs[BL31_CERT].bin = strdup(optarg); break; case BL32_ID: certs[BL32_CERT].bin = strdup(optarg); break; case BL33_ID: certs[BL33_CERT].bin = strdup(optarg); break; case BL2_CERT_ID: certs[BL2_CERT].fn = strdup(optarg); break; case TRUSTED_KEY_CERT_ID: certs[TRUSTED_KEY_CERT].fn = strdup(optarg); break; case BL30_KEY_CERT_ID: certs[BL30_KEY_CERT].fn = strdup(optarg); break; case BL30_CERT_ID: certs[BL30_CERT].fn = strdup(optarg); break; case BL31_KEY_CERT_ID: certs[BL31_KEY_CERT].fn = strdup(optarg); break; case BL31_CERT_ID: certs[BL31_CERT].fn = strdup(optarg); break; case BL32_KEY_CERT_ID: certs[BL32_KEY_CERT].fn = strdup(optarg); break; case BL32_CERT_ID: certs[BL32_CERT].fn = strdup(optarg); break; case BL33_KEY_CERT_ID: certs[BL33_KEY_CERT].fn = strdup(optarg); break; case BL33_CERT_ID: certs[BL33_CERT].fn = strdup(optarg); break; case ROT_KEY_ID: keys[ROT_KEY].fn = strdup(optarg); break; case TRUSTED_WORLD_KEY_ID: keys[TRUSTED_WORLD_KEY].fn = strdup(optarg); break; case NON_TRUSTED_WORLD_KEY_ID: keys[NON_TRUSTED_WORLD_KEY].fn = strdup(optarg); break; case BL30_KEY_ID: keys[BL30_KEY].fn = strdup(optarg); break; case BL31_KEY_ID: keys[BL31_KEY].fn = strdup(optarg); break; case BL32_KEY_ID: keys[BL32_KEY].fn = strdup(optarg); break; case BL33_KEY_ID: keys[BL33_KEY].fn = strdup(optarg); break; case '?': default: printf("%s\n", optarg); exit(1); } } /* Set the value of the NVCounters */ tf_nvcounter = NVCOUNTER_VALUE; non_tf_nvcounter = NVCOUNTER_VALUE; /* Check command line arguments */ check_cmd_params(); /* Register the new types and OIDs for the extensions */ if (ext_init(tbb_ext) != 0) { ERROR("Cannot initialize TBB extensions\n"); exit(1); } /* Indicate SHA256 as image hash algorithm in the certificate * extension */ md_info = EVP_sha256(); /* Get non-volatile counters NIDs */ CHECK_OID(tz_nvctr_nid, TZ_FW_NVCOUNTER_OID); CHECK_OID(ntz_nvctr_nid, NTZ_FW_NVCOUNTER_OID); /* Load private keys from files (or generate new ones) */ for (i = 0 ; i < NUM_KEYS ; i++) { /* First try to load the key from disk */ if (key_load(&keys[i], &err_code)) { /* Key loaded successfully */ continue; } /* Key not loaded. Check the error code */ if (err_code == KEY_ERR_MALLOC) { /* Cannot allocate memory. Abort. */ ERROR("Malloc error while loading '%s'\n", keys[i].fn); exit(1); } else if (err_code == KEY_ERR_LOAD) { /* File exists, but it does not contain a valid private * key. Abort. */ ERROR("Error loading '%s'\n", keys[i].fn); exit(1); } /* File does not exist, could not be opened or no filename was * given */ if (new_keys) { /* Try to create a new key */ NOTICE("Creating new key for '%s'\n", keys[i].desc); if (!key_create(&keys[i], key_alg)) { ERROR("Error creating key '%s'\n", keys[i].desc); exit(1); } } else { if (err_code == KEY_ERR_OPEN) { ERROR("Error opening '%s'\n", keys[i].fn); } else { ERROR("Key '%s' not specified\n", keys[i].desc); } exit(1); } } /* ********************************************************************* * BL2 certificate (Trusted Boot Firmware certificate): * - Self-signed with OEM ROT private key * - Extensions: * - TrustedFirmwareNVCounter (TODO) * - BL2 hash **********************************************************************/ CHECK_NULL(sk, sk_X509_EXTENSION_new_null()); /* Add the NVCounter as a critical extension */ CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT, tf_nvcounter)); sk_X509_EXTENSION_push(sk, nvctr_ext); /* Add hash of BL2 as an extension */ if (!sha_file(certs[BL2_CERT].bin, md)) { ERROR("Cannot calculate the hash of %s\n", certs[BL2_CERT].bin); exit(1); } CHECK_OID(hash_nid, BL2_HASH_OID); CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md_info, md, SHA256_DIGEST_LENGTH)); sk_X509_EXTENSION_push(sk, hash_ext); /* Create certificate. Signed with ROT key */ if (!cert_new(&certs[BL2_CERT], VAL_DAYS, 0, sk)) { ERROR("Cannot create %s\n", certs[BL2_CERT].cn); exit(1); } sk_X509_EXTENSION_free(sk); /* ********************************************************************* * Trusted Key certificate: * - Self-signed with OEM ROT private key * - Extensions: * - TrustedFirmwareNVCounter (TODO) * - TrustedWorldPK * - NonTrustedWorldPK **********************************************************************/ CHECK_NULL(sk, sk_X509_EXTENSION_new_null()); CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT, tf_nvcounter)); sk_X509_EXTENSION_push(sk, nvctr_ext); CHECK_OID(pk_nid, TZ_WORLD_PK_OID); CHECK_NULL(trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT, keys[TRUSTED_WORLD_KEY].key)); sk_X509_EXTENSION_push(sk, trusted_key_ext); CHECK_OID(pk_nid, NTZ_WORLD_PK_OID); CHECK_NULL(non_trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT, keys[NON_TRUSTED_WORLD_KEY].key)); sk_X509_EXTENSION_push(sk, non_trusted_key_ext); if (!cert_new(&certs[TRUSTED_KEY_CERT], VAL_DAYS, 0, sk)) { ERROR("Cannot create %s\n", certs[TRUSTED_KEY_CERT].cn); exit(1); } sk_X509_EXTENSION_free(sk); /* ********************************************************************* * BL30 Key certificate (Trusted SCP Firmware Key certificate): * - Self-signed with Trusted World key * - Extensions: * - TrustedFirmwareNVCounter (TODO) * - SCPFirmwareContentCertPK **********************************************************************/ if (bl30_present) { CHECK_NULL(sk, sk_X509_EXTENSION_new_null()); CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT, tf_nvcounter)); sk_X509_EXTENSION_push(sk, nvctr_ext); CHECK_OID(pk_nid, BL30_CONTENT_CERT_PK_OID); CHECK_NULL(trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT, keys[BL30_KEY].key)); sk_X509_EXTENSION_push(sk, trusted_key_ext); if (!cert_new(&certs[BL30_KEY_CERT], VAL_DAYS, 0, sk)) { ERROR("Cannot create %s\n", certs[BL30_KEY_CERT].cn); exit(1); } sk_X509_EXTENSION_free(sk); } /* ********************************************************************* * BL30 certificate (SCP Firmware Content certificate): * - Signed with Trusted World Key * - Extensions: * - TrustedFirmwareNVCounter (TODO) * - SCPFirmwareHash **********************************************************************/ if (bl30_present) { CHECK_NULL(sk, sk_X509_EXTENSION_new_null()); CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT, tf_nvcounter)); sk_X509_EXTENSION_push(sk, nvctr_ext); if (!sha_file(certs[BL30_CERT].bin, md)) { ERROR("Cannot calculate the hash of %s\n", certs[BL30_CERT].bin); exit(1); } CHECK_OID(hash_nid, BL30_HASH_OID); CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md_info, md, SHA256_DIGEST_LENGTH)); sk_X509_EXTENSION_push(sk, hash_ext); if (!cert_new(&certs[BL30_CERT], VAL_DAYS, 0, sk)) { ERROR("Cannot create %s\n", certs[BL30_CERT].cn); exit(1); } sk_X509_EXTENSION_free(sk); } /* ********************************************************************* * BL31 Key certificate (Trusted SoC Firmware Key certificate): * - Self-signed with Trusted World key * - Extensions: * - TrustedFirmwareNVCounter (TODO) * - SoCFirmwareContentCertPK **********************************************************************/ CHECK_NULL(sk, sk_X509_EXTENSION_new_null()); CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT, tf_nvcounter)); sk_X509_EXTENSION_push(sk, nvctr_ext); CHECK_OID(pk_nid, BL31_CONTENT_CERT_PK_OID); CHECK_NULL(trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT, keys[BL31_KEY].key)); sk_X509_EXTENSION_push(sk, trusted_key_ext); if (!cert_new(&certs[BL31_KEY_CERT], VAL_DAYS, 0, sk)) { ERROR("Cannot create %s\n", certs[BL31_KEY_CERT].cn); exit(1); } sk_X509_EXTENSION_free(sk); /* ********************************************************************* * BL31 certificate (SOC Firmware Content certificate): * - Signed with Trusted World Key * - Extensions: * - TrustedFirmwareNVCounter (TODO) * - BL31 hash **********************************************************************/ CHECK_NULL(sk, sk_X509_EXTENSION_new_null()); CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT, tf_nvcounter)); sk_X509_EXTENSION_push(sk, nvctr_ext); if (!sha_file(certs[BL31_CERT].bin, md)) { ERROR("Cannot calculate the hash of %s\n", certs[BL31_CERT].bin); exit(1); } CHECK_OID(hash_nid, BL31_HASH_OID); CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md_info, md, SHA256_DIGEST_LENGTH)); sk_X509_EXTENSION_push(sk, hash_ext); if (!cert_new(&certs[BL31_CERT], VAL_DAYS, 0, sk)) { ERROR("Cannot create %s\n", certs[BL31_CERT].cn); exit(1); } sk_X509_EXTENSION_free(sk); /* ********************************************************************* * BL32 Key certificate (Trusted OS Firmware Key certificate): * - Self-signed with Trusted World key * - Extensions: * - TrustedFirmwareNVCounter (TODO) * - TrustedOSFirmwareContentCertPK **********************************************************************/ if (bl32_present) { CHECK_NULL(sk, sk_X509_EXTENSION_new_null()); CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT, tf_nvcounter)); sk_X509_EXTENSION_push(sk, nvctr_ext); CHECK_OID(pk_nid, BL32_CONTENT_CERT_PK_OID); CHECK_NULL(trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT, keys[BL32_KEY].key)); sk_X509_EXTENSION_push(sk, trusted_key_ext); if (!cert_new(&certs[BL32_KEY_CERT], VAL_DAYS, 0, sk)) { ERROR("Cannot create %s\n", certs[BL32_KEY_CERT].cn); exit(1); } sk_X509_EXTENSION_free(sk); } /* ********************************************************************* * BL32 certificate (TrustedOS Firmware Content certificate): * - Signed with Trusted World Key * - Extensions: * - TrustedFirmwareNVCounter (TODO) * - BL32 hash **********************************************************************/ if (bl32_present) { CHECK_NULL(sk, sk_X509_EXTENSION_new_null()); CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT, tf_nvcounter)); sk_X509_EXTENSION_push(sk, nvctr_ext); if (!sha_file(certs[BL32_CERT].bin, md)) { ERROR("Cannot calculate the hash of %s\n", certs[BL32_CERT].bin); exit(1); } CHECK_OID(hash_nid, BL32_HASH_OID); CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md_info, md, SHA256_DIGEST_LENGTH)); sk_X509_EXTENSION_push(sk, hash_ext); if (!cert_new(&certs[BL32_CERT], VAL_DAYS, 0, sk)) { ERROR("Cannot create %s\n", certs[BL32_CERT].cn); exit(1); } sk_X509_EXTENSION_free(sk); } /* ********************************************************************* * BL33 Key certificate (Non Trusted Firmware Key certificate): * - Self-signed with Non Trusted World key * - Extensions: * - NonTrustedFirmwareNVCounter (TODO) * - NonTrustedFirmwareContentCertPK **********************************************************************/ CHECK_NULL(sk, sk_X509_EXTENSION_new_null()); CHECK_NULL(nvctr_ext, ext_new_nvcounter(ntz_nvctr_nid, EXT_CRIT, non_tf_nvcounter)); sk_X509_EXTENSION_push(sk, nvctr_ext); CHECK_OID(pk_nid, BL33_CONTENT_CERT_PK_OID); CHECK_NULL(non_trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT, keys[BL33_KEY].key)); sk_X509_EXTENSION_push(sk, non_trusted_key_ext); if (!cert_new(&certs[BL33_KEY_CERT], VAL_DAYS, 0, sk)) { ERROR("Cannot create %s\n", certs[BL33_KEY_CERT].cn); exit(1); } sk_X509_EXTENSION_free(sk); /* ********************************************************************* * BL33 certificate (Non-Trusted World Content certificate): * - Signed with Non-Trusted World Key * - Extensions: * - NonTrustedFirmwareNVCounter (TODO) * - BL33 hash **********************************************************************/ CHECK_NULL(sk, sk_X509_EXTENSION_new_null()); CHECK_NULL(nvctr_ext, ext_new_nvcounter(ntz_nvctr_nid, EXT_CRIT, non_tf_nvcounter)); sk_X509_EXTENSION_push(sk, nvctr_ext); if (!sha_file(certs[BL33_CERT].bin, md)) { ERROR("Cannot calculate the hash of %s\n", certs[BL33_CERT].bin); exit(1); } CHECK_OID(hash_nid, BL33_HASH_OID); CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md_info, md, SHA256_DIGEST_LENGTH)); sk_X509_EXTENSION_push(sk, hash_ext); if (!cert_new(&certs[BL33_CERT], VAL_DAYS, 0, sk)) { ERROR("Cannot create %s\n", certs[BL33_CERT].cn); exit(1); } sk_X509_EXTENSION_free(sk); /* Print the certificates */ if (print_cert) { for (i = 0 ; i < NUM_CERTIFICATES ; i++) { if (!certs[i].x) { continue; } printf("\n\n=====================================\n\n"); X509_print_fp(stdout, certs[i].x); } } /* Save created certificates to files */ for (i = 0 ; i < NUM_CERTIFICATES ; i++) { if (certs[i].x && certs[i].fn) { file = fopen(certs[i].fn, "w"); if (file != NULL) { i2d_X509_fp(file, certs[i].x); fclose(file); } else { ERROR("Cannot create file %s\n", certs[i].fn); } } } /* Save keys */ if (save_keys) { for (i = 0 ; i < NUM_KEYS ; i++) { if (!key_store(&keys[i])) { ERROR("Cannot save %s\n", keys[i].desc); } } } X509_EXTENSION_free(hash_ext); X509_EXTENSION_free(nvctr_ext); X509_EXTENSION_free(trusted_key_ext); X509_EXTENSION_free(non_trusted_key_ext); #ifndef OPENSSL_NO_ENGINE ENGINE_cleanup(); #endif CRYPTO_cleanup_all_ex_data(); return 0; }
TokenError _backend_createRequest(const RegutilInfo *info, const char *hostname, const char *password, char **request, size_t *reqlen) { // OpenSSL seeds the PRNG automatically, see the manual page for RAND_add. if (!RAND_status()) { fprintf(stderr, BINNAME ": no random state!\n"); return TokenError_NoRandomState; } // Abort if there are no requests *request = NULL; if (!info->pkcs10) return TokenError_Unknown; // Create certificate requests bool ok = true; CertReq *reqs = NULL; STACK *x509reqs = sk_new_null(); for (const RegutilPKCS10 *pkcs10 = info->pkcs10; pkcs10 != NULL; pkcs10 = pkcs10->next) { RSA *rsa = NULL; EVP_PKEY *privkey = NULL; X509_NAME *subject = NULL; X509_REQ *x509req = NULL; STACK_OF(X509_EXTENSION) *exts = NULL; // Check the parameters. // Maximum key size in OpenSSL: // http://www.mail-archive.com/[email protected]/msg58229.html if (!pkcs10->subjectDN || pkcs10->keySize < 1024 || pkcs10->keySize > 16384) goto req_error; // Generate key pair // FIXME deprecated function // TODO use OPENSSL_NO_DEPRECATED rsa = RSA_generate_key(pkcs10->keySize, RSA_F4, NULL, NULL); if (!rsa) goto req_error; privkey = EVP_PKEY_new(); if (!privkey) goto req_error; EVP_PKEY_assign_RSA(privkey, rsa); // Subject name subject = certutil_parse_dn(pkcs10->subjectDN, pkcs10->includeFullDN); if (!subject) goto req_error; // Create request x509req = X509_REQ_new(); if (!x509req || !X509_REQ_set_version(x509req, 0) || !X509_REQ_set_subject_name(x509req, subject) || !X509_REQ_set_pubkey(x509req, privkey)) { // yes this is correct(!) certutil_updateErrorString(); goto req_error; } // Set attributes exts = sk_X509_EXTENSION_new_null(); if (!exts) goto req_error; X509_EXTENSION *ext = makeKeyUsageExt(pkcs10->keyUsage); if (!ext || !sk_X509_EXTENSION_push(exts, ext)) goto req_error; if (!X509_REQ_add_extensions(x509req, exts)) { certutil_updateErrorString(); goto req_error; } exts = NULL; // Add signature if (!X509_REQ_sign(x509req, privkey, EVP_sha1())) { certutil_updateErrorString(); goto req_error; } // Store in list CertReq *req = malloc(sizeof(CertReq)); req->pkcs10 = pkcs10; req->privkey = privkey; req->rsa = rsa; req->x509 = x509req; req->next = reqs; reqs = req; sk_push(x509reqs, (char*)x509req); continue; req_error: // Clean up and set error flag if (privkey) EVP_PKEY_free(privkey); else if (rsa) RSA_free(rsa); X509_NAME_free(subject); sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); X509_REQ_free(x509req); ok = false; } TokenError error = TokenError_Unknown; if (ok) { // Determine filename from certificate name char *filename = certutil_makeFilename(X509_REQ_get_subject_name(reqs->x509)); // Build the certificate request request_wrap(x509reqs, request, reqlen); if (*request && filename) { // Create the key file in ~/cbt/name.p12 FILE *keyfile = platform_openLocked(filename, Platform_OpenCreate); if (!keyfile) { error = TokenError_CantCreateFile; } else { error = saveKeys(reqs, hostname, password, keyfile); if (!platform_closeLocked(keyfile) && !error) error = TokenError_CantCreateFile; } } if (filename) free(filename); if (error && *request) free(*request); } // Free reqs while (reqs) { RSA_free(reqs->rsa); // This free's privkey too X509_REQ_free(reqs->x509); CertReq *next = reqs->next; free(reqs); reqs = next; } sk_free(x509reqs); return error; }
int mkreq(X509_REQ **req, EVP_PKEY **pkeyp, int bits, int serial, int days) { X509_REQ *x; EVP_PKEY *pk; RSA *rsa; X509_NAME *name=NULL; STACK_OF(X509_EXTENSION) *exts = NULL; if ((pk=EVP_PKEY_new()) == NULL) goto err; if ((x=X509_REQ_new()) == NULL) goto err; rsa=RSA_generate_key(bits,RSA_F4,callback,NULL); if (!EVP_PKEY_assign_RSA(pk,rsa)) goto err; rsa=NULL; X509_REQ_set_pubkey(x,pk); name=X509_REQ_get_subject_name(x); /* This function creates and adds the entry, working out the * correct string type and performing checks on its length. * Normally we'd check the return value for errors... */ X509_NAME_add_entry_by_txt(name,"C", MBSTRING_ASC, "UK", -1, -1, 0); X509_NAME_add_entry_by_txt(name,"CN", MBSTRING_ASC, "OpenSSL Group", -1, -1, 0); #ifdef REQUEST_EXTENSIONS /* Certificate requests can contain extensions, which can be used * to indicate the extensions the requestor would like added to * their certificate. CAs might ignore them however or even choke * if they are present. */ /* For request extensions they are all packed in a single attribute. * We save them in a STACK and add them all at once later... */ exts = sk_X509_EXTENSION_new_null(); /* Standard extenions */ add_ext(exts, NID_key_usage, "critical,digitalSignature,keyEncipherment"); /* This is a typical use for request extensions: requesting a value for * subject alternative name. */ add_ext(exts, NID_subject_alt_name, "email:[email protected]"); /* Some Netscape specific extensions */ add_ext(exts, NID_netscape_cert_type, "client,email"); #ifdef CUSTOM_EXT /* Maybe even add our own extension based on existing */ { int nid; nid = OBJ_create("1.2.3.4", "MyAlias", "My Test Alias Extension"); X509V3_EXT_add_alias(nid, NID_netscape_comment); add_ext(x, nid, "example comment alias"); } #endif /* Now we've created the extensions we add them to the request */ X509_REQ_add_extensions(x, exts); sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); #endif if (!X509_REQ_sign(x,pk,EVP_md5())) goto err; *req=x; *pkeyp=pk; return(1); err: return(0); }
int32_t HttpsGenCertReq( HttpsCertReqInfo_t *pCertReqInfo, unsigned char *pPrivbuf, unsigned char *pCertbuf, HttpsCertReqParams_t *pParams ) { EVP_PKEY *pkey = NULL; HX509Req_t *preq = NULL; #ifdef OPENSSL_9_7 const EVP_MD *pDigest; #else EVP_MD *pDigest = NULL; #endif /*OPENSSL_9_7*/ int32_t iRetVal; unsigned char aSubAltName[HTTPS_PARAMS_SUB_NAME_LEN]; bool bFlag = FALSE; STACK_OF(X509_EXTENSION) *skExtensions = NULL; X509_EXTENSION *pSubExt = NULL; unsigned char ucCT; int32_t uileng; /** * Input Validations... */ if (pCertReqInfo == NULL) { Trace(HTTPS_ID, TRACE_SEVERE, "HttpsGenCertReq:: Invalid parameters\n"); return OF_FAILURE; } /** * Allocate space for the public-private key pair.. */ if ((pkey = EVP_PKEY_new()) == NULL) { Trace(HTTPS_ID, TRACE_SEVERE, "HttpsGenCertReq:: MemAlloc failure\n"); return OF_FAILURE; } /** * Generate a public-private key pair.. */ switch (pCertReqInfo->usCertType) { case RSA_MD5: case RSA_SHA1: if ((pCertReqInfo->cr_params.rsa_params.usNumBits < MIN_KEY_LENGTH)) { Trace(HTTPS_ID, TRACE_SEVERE, "HttpsGenCertReq : Invalid RSA parameters\n"); EVP_PKEY_free(pkey); return OF_FAILURE; } if (!EVP_PKEY_assign_RSA(pkey, RSA_generate_key(pCertReqInfo->cr_params.rsa_params.usNumBits, 0x10001, NULL, NULL))) { Trace(HTTPS_ID, TRACE_SEVERE, "HttpsGenCertReq: EVP_PKEY assign failed\n"); EVP_PKEY_free(pkey); return OF_FAILURE; } ucCT='r'; if (pCertReqInfo->usCertType == RSA_MD5) { pDigest = (EVP_MD *) EVP_md5(); } else { pDigest = (EVP_MD *) EVP_sha1(); } break; default: Trace(HTTPS_ID, TRACE_SEVERE, "HttpsGenCertReq:: Invalid certificate type\n"); EVP_PKEY_free(pkey); return OF_FAILURE; } /** * Prepare the Certificate Request.. */ if ((preq = HttpsCertReqNew()) == NULL) { Trace(HTTPS_ID, TRACE_SEVERE, "HttpsGenCertReq:: X509_req_new failed\n"); EVP_PKEY_free(pkey); return OF_FAILURE; } /** * Version Number.. */ if (!ASN1_INTEGER_set(preq->req_info->version, 0L)) { Trace(HTTPS_ID, TRACE_SEVERE, "HttpsGenCertReq:: ASN1_INTEGER_set failed\n"); HttpsCertReqFree(preq); EVP_PKEY_free(pkey); return OF_FAILURE; } /** * Subject Name...Filled with two RDNs... */ /** * RDN # 1 : Country Name... */ if (!Httpsadd_DN_object((HX509Name_t *) preq->req_info->subject, NULL, NULL, (char *) pParams->ucCn, NID_countryName, 2, 2)) { Trace(HTTPS_ID, TRACE_SEVERE, "HttpsGenCertReq:: Httpsadd_DN_object failed\n"); HttpsCertReqFree(preq); EVP_PKEY_free(pkey); return OF_FAILURE; } #ifdef OPENSSL_9_7 if (NID_postalCode == 0) { NID_postalCode = OBJ_create("2.5.4.17", "2.5.4.17", "postal code attribute"); } #endif /** * RDN #New::2: Postal code... */ if (!Httpsadd_DN_object((HX509Name_t *) preq->req_info->subject, NULL, NULL, (char *) pParams->aPostalCode, NID_postalCode, 0, 10)) { Trace(HTTPS_ID, TRACE_SEVERE, "HttpsGenCertReq:: Httpsadd_DN_object failed\n"); HttpsCertReqFree(preq); EVP_PKEY_free(pkey); return OF_FAILURE; } /** * RDN #3: State.. */ if (!Httpsadd_DN_object((HX509Name_t *) preq->req_info->subject, NULL, NULL, (char *) pParams->aState, NID_stateOrProvinceName, 0, 50)) { Trace(HTTPS_ID, TRACE_SEVERE, "HttpsGenCertReq:: Httpsadd_DN_object failed\n"); HttpsCertReqFree(preq); EVP_PKEY_free(pkey); return OF_FAILURE; } /** * RDN #New::4: Locality Name... */ if (!Httpsadd_DN_object((HX509Name_t *) preq->req_info->subject, NULL, NULL, (char *) pParams->aCity, NID_localityName, 0, 50)) { Trace(HTTPS_ID, TRACE_SEVERE, "HttpsGenCertReq:: Httpsadd_DN_object failed\n"); HttpsCertReqFree(preq); EVP_PKEY_free(pkey); return OF_FAILURE; } /** * RDN #5 : Organization .. */ if (!Httpsadd_DN_object((HX509Name_t *) preq->req_info->subject, NULL, NULL, (char *) pParams->aOrg, NID_organizationName, 0, 50)) { Trace(HTTPS_ID, TRACE_SEVERE, "HttpsGenCertReq:: Httpsadd_DN_object failed\n"); HttpsCertReqFree(preq); EVP_PKEY_free(pkey); return OF_FAILURE; } /** * RDN #6 : Department .. */ if (!Httpsadd_DN_object((HX509Name_t *) preq->req_info->subject, NULL, NULL, (char *) pParams->aDept, NID_organizationalUnitName, 0, 50)) { Trace(HTTPS_ID, TRACE_SEVERE, "HttpsGenCertReq:: Httpsadd_DN_object failed\n"); HttpsCertReqFree(preq); EVP_PKEY_free(pkey); return OF_FAILURE; } /** * RDN #7 : Common Name (Subject)... */ if (!Httpsadd_DN_object((HX509Name_t *) preq->req_info->subject, NULL, NULL, (char *) pParams->ucSub, NID_commonName, 0, 50)) { Trace(HTTPS_ID, TRACE_SEVERE, "HttpsGenCertReq:: Httpsadd_DN_object failed\n"); HttpsCertReqFree(preq); EVP_PKEY_free(pkey); return OF_FAILURE; } of_memset( aSubAltName, 0, HTTPS_PARAMS_SUB_NAME_LEN); if (strlen((char *) pParams->aIpAddr)) { of_strcat((char *) aSubAltName, "IP:"); of_strcat((char *) aSubAltName, (char *) pParams->aIpAddr); bFlag = TRUE; } if (strlen((char *) pParams->aEmailId)) { if (bFlag) { of_strcat((char *) aSubAltName, ",email:"); } else { of_strcat((char *) aSubAltName, "email:"); } of_strcat((char *) aSubAltName, (char *) pParams->aEmailId); bFlag = TRUE; } if (strlen((char *) pParams->aDomain)) { if (bFlag) { of_strcat((char *) aSubAltName, ",DNS:"); } else { of_strcat((char *) aSubAltName, "DNS:"); } of_strcat((char *) aSubAltName, (char *) pParams->aDomain); bFlag = TRUE; } /** * Adding subject alt name extension to the request. */ if ( of_strlen((char *) aSubAltName)) { skExtensions = sk_X509_EXTENSION_new_null(); if (skExtensions == NULL) { Trace(HTTPS_ID, TRACE_SEVERE, "HttpsGenCertReq:: sk_X509_EXTENSION_new_null failed\n"); HttpsCertReqFree(preq); EVP_PKEY_free(pkey); return OF_FAILURE; } pSubExt = X509V3_EXT_conf_nid(NULL, NULL, NID_subject_alt_name, (char *) aSubAltName); if (pSubExt) { sk_X509_EXTENSION_push(skExtensions, pSubExt); } iRetVal = X509_REQ_add_extensions(preq, skExtensions); if (iRetVal == 0) { Trace(HTTPS_ID, TRACE_SEVERE, "HttpsGenCertReq:: X509_REQ_add_extensions failed\n"); HttpsCertReqFree(preq); EVP_PKEY_free(pkey); return OF_FAILURE; } sk_X509_EXTENSION_pop_free(skExtensions, X509_EXTENSION_free); } /* strlen sub alt */ /** * Set the public key.. */ if (!X509_REQ_set_pubkey(preq, pkey)) { Trace(HTTPS_ID, TRACE_SEVERE, "HttpsGenCertReq:: X509_REQ_sign failed\n"); HttpsCertReqFree(preq); EVP_PKEY_free(pkey); return OF_FAILURE; } /** * Sign the CertReq Info.. */ if (!X509_REQ_sign(preq, pkey, pDigest)) { Trace(HTTPS_ID, TRACE_SEVERE, "HttpsGenCertReq:: X509_REQ_sign failed\n"); HttpsCertReqFree(preq); EVP_PKEY_free(pkey); return OF_FAILURE; } /** * Write the Private Key into the file... */ if (HttpsWritetoFile(pPrivbuf, HTTPS_PRIV_KEY, pkey, ucCT, pParams->aIdName)) { Trace(HTTPS_ID, TRACE_SEVERE, "HttpsGenCertReq:: HttpsWritetoFile failed #1\n"); HttpsCertReqFree(preq); EVP_PKEY_free(pkey); return OF_FAILURE; } /** * Write the Certificate Request into the file... */ if (HttpsWritetoFile(pCertbuf, HTTPS_CERT_REQ, preq, ucCT, pParams->aIdName)) { Trace(HTTPS_ID, TRACE_SEVERE, "HttpsGenCertReq:: HttpsWritetoFile failed #2\n"); HttpsDeleteCerts(pParams->aIdName, 's'); HttpsCertReqFree(preq); EVP_PKEY_free(pkey); return OF_FAILURE; } uileng=strlen((char *) pCertbuf); if (uileng > 2047) { Trace(HTTPS_ID, TRACE_SEVERE, "pCertbuf length exceeds 2k\n"); HttpsDeleteCerts(pParams->aIdName, 's'); HttpsCertReqFree(preq); EVP_PKEY_free(pkey); return OF_FAILURE; } Trace(HTTPS_ID, TRACE_INFO, "Generation of Certificate Request done\n"); HttpsCertReqFree(preq); EVP_PKEY_free(pkey); return OF_SUCCESS; } /* HttpsGenCertReq() */
// reads the request req_filename and creates a modified creq_filename with the commitment extension added void writeCommitmentCSR(BIGNUM *commitment_c, char *privkey_filename, char *req_filename, char *creq_filename) { FILE *fp; /* read in the request */ X509_REQ *req; if (!(fp = fopen(req_filename, "r"))) critical_error("Error reading request file"); if (!(req = PEM_read_X509_REQ(fp, NULL, NULL, NULL))) critical_error("Error reading request in file"); fclose(fp); /* read in the private key */ EVP_PKEY *pkey; if (!(fp = fopen(privkey_filename, "r"))) critical_error("Error reading private key file"); if (!(pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL))) critical_error("Error reading private key in file"); fclose(fp); /* create the new request */ X509_REQ *creq; if (!(creq = X509_REQ_new())) critical_error("Failed to create X509_REQ object"); X509_REQ_set_pubkey(creq, pkey); // gets subj from initial requests and adds it to new one X509_NAME *subj = X509_REQ_get_subject_name(req); if (X509_REQ_set_subject_name(creq, subj) != 1) critical_error("Error adding subject to request"); // enable the commitment extension handling (retrieve/print as string) int nid = _commitmentExt_start(); // get extensions stack of original request STACK_OF(X509_EXTENSION) *extlist = X509_REQ_get_extensions(req); // if no extensions, create new stack if (extlist==NULL) { extlist = sk_X509_EXTENSION_new_null(); } else { // else check that the extension isn't already there (error!) X509_EXTENSION *tmp = (X509_EXTENSION*) X509V3_get_d2i(extlist, nid, NULL, NULL); if (tmp!=NULL) critical_error("Aborting process: CSR already contains commitment extension!\n"); } // create commitment extension storing C value as a hex string X509_EXTENSION *exCommitment = (X509_EXTENSION*) X509V3_EXT_conf_nid(NULL, NULL, nid, BN_bn2hex(commitment_c)); if (!exCommitment) critical_error("error creating commitment extension"); // push commitment extension into stack sk_X509_EXTENSION_push(extlist, exCommitment); // assign extensions to the new request if (!X509_REQ_add_extensions(creq, extlist)) critical_error("Error adding extensions to the request"); sk_X509_EXTENSION_pop_free(extlist, X509_EXTENSION_free); ///////////////////////////////////////////////////////////////////// /* pick the correct digest and sign the new request */ EVP_MD *digest; if (EVP_PKEY_type(pkey->type) == EVP_PKEY_DSA) digest = (EVP_MD*) EVP_dss1(); else if (EVP_PKEY_type(pkey->type) == EVP_PKEY_RSA) digest = (EVP_MD*) EVP_sha1(); else critical_error("Error checking public key for a valid digest"); if (!(X509_REQ_sign(creq, pkey, digest))) critical_error("Error signing request"); /* write the modified request */ if (!(fp = fopen(creq_filename, "w"))) critical_error("Error writing to request file"); if (PEM_write_X509_REQ(fp, creq) != 1) critical_error("Error while writing request"); fclose(fp); // cleanup _commitmentExt_end(); EVP_PKEY_free(pkey); X509_REQ_free(req); X509_REQ_free(creq); }