/* * This function adds the TBB extensions to the internal extension list * maintained by OpenSSL so they can be used later. * * It also initializes the methods to print the contents of the extension. If an * alias is specified in the TBB extension, we reuse the methods of the alias. * Otherwise, only methods for V_ASN1_INTEGER and V_ASN1_OCTET_STRING are * provided. Any other type will be printed as a raw ascii string. * * Return: 0 = success, Otherwise: error */ int ext_init(void) { cmd_opt_t cmd_opt; ext_t *ext; X509V3_EXT_METHOD *m; int nid, ret; unsigned int i; for (i = 0; i < num_extensions; i++) { ext = &extensions[i]; /* Register command line option */ if (ext->opt) { cmd_opt.long_opt.name = ext->opt; cmd_opt.long_opt.has_arg = required_argument; cmd_opt.long_opt.flag = NULL; cmd_opt.long_opt.val = CMD_OPT_EXT; cmd_opt.help_msg = ext->help_msg; cmd_opt_add(&cmd_opt); } /* Register the extension OID in OpenSSL */ if (ext->oid == NULL) { continue; } nid = OBJ_create(ext->oid, ext->sn, ext->ln); if (ext->alias) { X509V3_EXT_add_alias(nid, ext->alias); } else { m = &ext->method; memset(m, 0x0, sizeof(X509V3_EXT_METHOD)); switch (ext->asn1_type) { case V_ASN1_INTEGER: m->it = ASN1_ITEM_ref(ASN1_INTEGER); m->i2s = (X509V3_EXT_I2S)i2s_ASN1_INTEGER; m->s2i = (X509V3_EXT_S2I)s2i_ASN1_INTEGER; break; case V_ASN1_OCTET_STRING: m->it = ASN1_ITEM_ref(ASN1_OCTET_STRING); m->i2s = (X509V3_EXT_I2S)i2s_ASN1_OCTET_STRING; m->s2i = (X509V3_EXT_S2I)s2i_ASN1_OCTET_STRING; break; default: continue; } m->ext_nid = nid; ret = X509V3_EXT_add(m); if (!ret) { ERR_print_errors_fp(stdout); return 1; } } } return 0; }
static int mkcert(X509 **x509p, EVP_PKEY **pkeyp, int bits, int serial, int days) { X509 *x; EVP_PKEY *pk; RSA *rsa; X509_NAME *name=NULL; if ((pkeyp == NULL) || (*pkeyp == NULL)) { if ((pk=EVP_PKEY_new()) == NULL) { abort(); return(0); } } else pk= *pkeyp; if ((x509p == NULL) || (*x509p == NULL)) { if ((x=X509_new()) == NULL) goto err; } else x= *x509p; if (bits != 0){ rsa=RSA_generate_key(bits,RSA_F4,callback,NULL); if (!EVP_PKEY_assign_RSA(pk,rsa)) { abort(); goto err; } rsa=NULL; } X509_set_version(x,2); ASN1_INTEGER_set(X509_get_serialNumber(x),serial); X509_gmtime_adj(X509_get_notBefore(x),0); X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days); X509_set_pubkey(x,pk); name=X509_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,(const unsigned char *) "UK", -1, -1, 0); X509_NAME_add_entry_by_txt(name,"CN", MBSTRING_ASC, (const unsigned char *) _cert_cn, -1, -1, 0); /* Its self signed so set the issuer name to be the same as the * subject. */ X509_set_issuer_name(x,name); /* Add various extensions: standard extensions */ add_ext(x, NID_basic_constraints, "critical,CA:TRUE"); add_ext(x, NID_key_usage, "critical,keyCertSign,cRLSign"); add_ext(x, NID_subject_key_identifier, "hash"); /* Some Netscape specific extensions */ add_ext(x, NID_netscape_cert_type, "sslCA"); add_ext(x, NID_netscape_comment, "example comment extension"); #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 if (!X509_sign(x,pk,EVP_sha1())) goto err; *x509p=x; *pkeyp=pk; return(1); err: return(0); }
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); }
// enables handling of the extension as a string using an appropriate OID static int _commitmentExt_start() { int nid = OBJ_create(COMMITMENT_OID_C, COMMITMENT_OID_SNAME, COMMITMENT_OID_LNAME); X509V3_EXT_add_alias(nid, NID_netscape_comment); return nid; }
int32_t mkcert(X509 **x509p, EVP_PKEY **pkeyp, int32_t bits, int32_t serial, int32_t days) { bool bCreatedKey = false; bool bCreatedX509 = false; // ----------------- X509 * x = NULL; EVP_PKEY * pk = NULL; RSA * rsa = NULL; X509_NAME * name = NULL; if ((pkeyp == NULL) || (*pkeyp == NULL)) { if ((pk = EVP_PKEY_new()) == NULL) { abort(); // todo //return(0); unneeded after abort. } bCreatedKey = true; } else pk = *pkeyp; // ----------------------------------------- if ((x509p == NULL) || (*x509p == NULL)) { if ((x = X509_new()) == NULL) { if (bCreatedKey) { EVP_PKEY_free(pk); } return(0); } bCreatedX509 = true; } else x = *x509p; // ----------------------------------------- // pRsaKey = RSA_generate_key(1024, 0x010001, NULL, NULL); #ifdef ANDROID rsa = RSA_new(); BIGNUM * e1 = BN_new(); if ((NULL == rsa) || (NULL == e1)) abort(); // todo // BN_set_word(e1, 65537); BN_set_word(e1, RSA_F4); if (!RSA_generate_key_ex(rsa, bits, e1, NULL)) abort(); // todo BN_free(e1); #else rsa = RSA_generate_key(bits, RSA_F4, callback, NULL); #endif // ----------------------------------------- if (!EVP_PKEY_assign_RSA(pk, rsa)) { abort(); // todo //return(0); undeeded after abort. } // ------------------------------ rsa = NULL; X509_set_version(x, 2); ASN1_INTEGER_set(X509_get_serialNumber(x), serial); X509_gmtime_adj (X509_get_notBefore(x), 0); X509_gmtime_adj (X509_get_notAfter (x), static_cast<int64_t>(60*60*24*days)); X509_set_pubkey (x, pk); name = X509_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, (const uint8_t *)"UK", -1, -1, 0); X509_NAME_add_entry_by_txt(name,"CN", MBSTRING_ASC, (const uint8_t *)"OpenSSL Group", -1, -1, 0); /* Its self signed so set the issuer name to be the same as the * subject. */ X509_set_issuer_name(x, name); // ---------------------------------------------------------------------------- /* Add various extensions: standard extensions */ char * szConstraints = new char[100](); char * szKeyUsage = new char[100](); char * szSubjectKeyID = new char[100](); char * szCertType = new char[100](); char * szComment = new char[100](); // ---------------------------------------------------------------------------- opentxs::OTString::safe_strcpy(szConstraints, "critical,CA:TRUE", 99); opentxs::OTString::safe_strcpy(szKeyUsage, "critical,keyCertSign,cRLSign", 99); opentxs::OTString::safe_strcpy(szSubjectKeyID, "hash", 99); opentxs::OTString::safe_strcpy(szCertType, "sslCA", 99); opentxs::OTString::safe_strcpy(szComment, "example comment extension", 99); // ---------------------------------------------------------------------------- add_ext(x, NID_basic_constraints, szConstraints); add_ext(x, NID_key_usage, szKeyUsage); add_ext(x, NID_subject_key_identifier, szSubjectKeyID); add_ext(x, NID_netscape_cert_type, szCertType); // Some Netscape specific extensions add_ext(x, NID_netscape_comment, szComment); // Some Netscape specific extensions // ---------------------------------------------------------------------------- delete [] szConstraints; szConstraints = NULL; delete [] szKeyUsage; szKeyUsage = NULL; delete [] szSubjectKeyID; szSubjectKeyID = NULL; delete [] szCertType; szCertType = NULL; delete [] szComment; szComment = NULL; // ---------------------------------------------------------------------------- #ifdef CUSTOM_EXT // Maybe even add our own extension based on existing { int32_t 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 // ------------------------------ if (!X509_sign(x, pk, EVP_md5()) || // TODO security: md5 ??? (NULL == x509p) || (NULL == pkeyp)) { // ERROR // if (bCreatedX509) X509_free(x); // NOTE: not sure if x owns pk, in which case pk is already freed above. // Todo: find out and then determine whether or not to uncomment this. // (Presumably this would be a rare occurrence anyway.) // // if (bCreatedKey) // EVP_PKEY_free(pk); x = NULL; pk = NULL; return 0; } // ------------------------------ *x509p = x; *pkeyp = pk; return(1); }