MCPcopy Create free account
hub / github.com/apple/foundationdb / makeCertNative

Function makeCertNative

flow/MkCert.cpp:189–254  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

187}
188
189CertAndKeyNative makeCertNative(CertSpecRef spec, CertAndKeyNative issuer) {
190 // issuer key/cert must be both set or both null (self-signed case)
191 ASSERT(issuer.valid() || issuer.null());
192
193 auto const isSelfSigned = issuer.null();
194 auto keypair = makeEcP256();
195 auto newX = ::X509_new();
196 OSSL_ASSERT(newX);
197 auto x509Guard = ScopeExit([&newX]() {
198 if (newX)
199 ::X509_free(newX);
200 });
201 auto smartX = std::shared_ptr<X509>(newX, &::X509_free);
202 newX = nullptr;
203 auto x = smartX.get();
204 OSSL_ASSERT(0 < ::X509_set_version(x, 2 /*X509_VERSION_3*/));
205 auto serialPtr = ::X509_get_serialNumber(x);
206 OSSL_ASSERT(serialPtr);
207 OSSL_ASSERT(0 < ::ASN1_INTEGER_set(serialPtr, spec.serialNumber));
208 auto notBefore = ::X509_getm_notBefore(x);
209 OSSL_ASSERT(notBefore);
210 OSSL_ASSERT(::X509_gmtime_adj(notBefore, spec.offsetNotBefore));
211 auto notAfter = ::X509_getm_notAfter(x);
212 OSSL_ASSERT(notAfter);
213 OSSL_ASSERT(::X509_gmtime_adj(notAfter, spec.offsetNotAfter));
214 OSSL_ASSERT(0 < ::X509_set_pubkey(x, keypair.nativeHandle()));
215 auto subjectName = ::X509_get_subject_name(x);
216 OSSL_ASSERT(subjectName);
217 for (const auto& entry : spec.subjectName) {
218 // field names are expected to null-terminate
219 auto fieldName = entry.field.toString();
220 OSSL_ASSERT(0 <
221 ::X509_NAME_add_entry_by_txt(
222 subjectName, fieldName.c_str(), MBSTRING_ASC, entry.bytes.begin(), entry.bytes.size(), -1, 0));
223 }
224 auto issuerName = ::X509_get_issuer_name(x);
225 OSSL_ASSERT(issuerName);
226 OSSL_ASSERT(::X509_set_issuer_name(x, (isSelfSigned ? subjectName : ::X509_get_subject_name(issuer.cert.get()))));
227 auto ctx = X509V3_CTX{};
228 X509V3_set_ctx_nodb(&ctx);
229 ::X509V3_set_ctx(&ctx, (isSelfSigned ? x : issuer.cert.get()), x, nullptr, nullptr, 0);
230 for (const auto& entry : spec.extensions) {
231 // extension field names and values are expected to null-terminate
232 auto extName = entry.field.toString();
233 auto extValue = entry.bytes.toString();
234 auto extNid = ::OBJ_txt2nid(extName.c_str());
235 if (extNid == NID_undef) {
236 TraceEvent(SevWarnAlways, "MkCertInvalidExtName").suppressFor(10).detail("Name", extName);
237 throw tls_error();
238 }
239#ifdef OPENSSL_IS_BORINGSSL
240 auto ext = ::X509V3_EXT_nconf_nid(nullptr, &ctx, extNid, const_cast<char*>(extValue.c_str()));
241#else
242 auto ext = ::X509V3_EXT_nconf_nid(nullptr, &ctx, extNid, extValue.c_str());
243#endif
244 OSSL_ASSERT(ext);
245 auto extGuard = ScopeExit([ext]() { ::X509_EXTENSION_free(ext); });
246 OSSL_ASSERT(::X509_add_ext(x, ext, -1));

Callers 2

makeMethod · 0.85
makeCertChainFunction · 0.85

Calls 12

makeEcP256Function · 0.85
ScopeExitClass · 0.85
TraceEventClass · 0.85
nullMethod · 0.80
detailMethod · 0.80
getMethod · 0.65
validMethod · 0.45
nativeHandleMethod · 0.45
toStringMethod · 0.45
c_strMethod · 0.45
beginMethod · 0.45
sizeMethod · 0.45

Tested by

no test coverage detected