X509_EXTENSION* AuthorityKeyIdentifierExtension::getX509Extension() { X509_EXTENSION *ret; AUTHORITY_KEYID *authKeyId; ByteArray temp; authKeyId = AUTHORITY_KEYID_new(); if (this->keyIdentifier.size() > 0) { authKeyId->keyid = ASN1_OCTET_STRING_new(); temp = this->keyIdentifier; ASN1_OCTET_STRING_set(authKeyId->keyid, temp.getDataPointer(), temp.size()); } if (this->authorityCertIssuer.getNumberOfEntries() > 0) { authKeyId->issuer = this->authorityCertIssuer.getInternalGeneralNames(); } if (this->serialNumber >= 0) { authKeyId->serial = ASN1_INTEGER_new(); ASN1_INTEGER_set(authKeyId->serial, this->serialNumber); } ret = X509V3_EXT_i2d(NID_authority_key_identifier, this->critical?1:0, (void *)authKeyId); AUTHORITY_KEYID_free(authKeyId); return ret; }
X509_EXTENSION* SubjectKeyIdentifierExtension::getX509Extension() { X509_EXTENSION *ret; ASN1_OCTET_STRING *octetString; ByteArray data; ret = X509_EXTENSION_new(); octetString = ASN1_OCTET_STRING_new(); data = this->keyIdentifier; ASN1_OCTET_STRING_set(octetString, data.getDataPointer(), data.size()); ret = X509V3_EXT_i2d(NID_subject_key_identifier, this->critical?1:0, (void *)octetString); return ret; }
X509_EXTENSION* DeltaCRLIndicatorExtension::getX509Extension() { X509_EXTENSION *ret; ASN1_INTEGER* baseCrlNumber; ret = X509_EXTENSION_new(); int rc; baseCrlNumber = ASN1_INTEGER_new(); ASN1_INTEGER_set(baseCrlNumber, this->baseCrlNumber); ret = X509V3_EXT_i2d(NID_delta_crl, this->critical?1:0, (void *)baseCrlNumber); return ret; }
/* * 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; }