@@ -33,6 +33,7 @@ using v8::BackingStoreOnFailureMode;
3333using v8::Boolean;
3434using v8::Context;
3535using v8::Date;
36+ using v8::DictionaryTemplate;
3637using v8::EscapableHandleScope;
3738using v8::Function;
3839using v8::FunctionCallbackInfo;
@@ -46,6 +47,7 @@ using v8::NewStringType;
4647using v8::Object;
4748using v8::String;
4849using v8::Uint32;
50+ using v8::Undefined;
4951using v8::Value;
5052
5153namespace crypto {
@@ -735,116 +737,86 @@ MaybeLocal<Value> GetCurveName(Environment* env, const int nid) {
735737
736738MaybeLocal<Object> X509ToObject(Environment* env, const X509View& cert) {
737739 EscapableHandleScope scope(env->isolate());
738- Local<Object> info = Object::New(env->isolate());
739-
740- if (!Set<Value>(env,
741- info,
742- env->subject_string(),
743- GetX509NameObject(env, cert.getSubjectName())) ||
744- !Set<Value>(env,
745- info,
746- env->issuer_string(),
747- GetX509NameObject(env, cert.getIssuerName())) ||
748- !Set<Value>(env,
749- info,
750- env->subjectaltname_string(),
751- GetSubjectAltNameString(env, cert)) ||
752- !Set<Value>(env,
753- info,
754- env->infoaccess_string(),
755- GetInfoAccessString(env, cert)) ||
756- !Set<Boolean>(env,
757- info,
758- env->ca_string(),
759- Boolean::New(env->isolate(), cert.isCA()))) [[unlikely]] {
760- return {};
761- }
762740
763- if (!cert.ifRsa([&](const ncrypto::Rsa& rsa) {
764- auto pub_key = rsa.getPublicKey();
765- if (!Set<Value>(env,
766- info,
767- env->modulus_string(),
768- GetModulusString(env, pub_key.n)) ||
769- !Set<Value>(env,
770- info,
771- env->bits_string(),
772- Integer::New(env->isolate(),
773- BignumPointer::GetBitCount(pub_key.n))) ||
774- !Set<Value>(env,
775- info,
776- env->exponent_string(),
777- GetExponentString(env, pub_key.e)) ||
778- !Set<Object>(env, info, env->pubkey_string(), GetPubKey(env, rsa)))
779- [[unlikely]] {
780- return false;
781- }
782- return true;
783- })) [[unlikely]] {
784- return {};
741+ auto tmpl = env->x509_dictionary_template();
742+ if (tmpl.IsEmpty()) {
743+ static constexpr std::string_view names[] = {
744+ "subject",
745+ "issuer",
746+ "subjectaltname",
747+ "infoAccess",
748+ "ca",
749+ "modulus",
750+ "exponent",
751+ "pubkey",
752+ "bits",
753+ "valid_from",
754+ "valid_to",
755+ "fingerprint",
756+ "fingerprint256",
757+ "fingerprint512",
758+ "ext_key_usage",
759+ "serialNumber",
760+ "raw",
761+ "asn1Curve",
762+ "nistCurve",
763+ };
764+ tmpl = DictionaryTemplate::New(env->isolate(), names);
765+ env->set_x509_dictionary_template(tmpl);
785766 }
786767
787- if (!cert.ifEc([&](const ncrypto::Ec& ec) {
788- const auto group = ec.getGroup();
789-
790- if (!Set<Value>(
791- env, info, env->bits_string(), GetECGroupBits(env, group)) ||
792- !Set<Value>(
793- env, info, env->pubkey_string(), GetECPubKey(env, group, ec)))
794- [[unlikely]] {
795- return false;
796- }
797-
798- const int nid = ec.getCurve();
799- if (nid != 0) [[likely]] {
800- // Curve is well-known, get its OID and NIST nick-name (if it has
801- // one).
802-
803- if (!Set<Value>(env,
804- info,
805- env->asn1curve_string(),
806- GetCurveName<OBJ_nid2sn>(env, nid)) ||
807- !Set<Value>(env,
808- info,
809- env->nistcurve_string(),
810- GetCurveName<EC_curve_nid2nist>(env, nid)))
811- [[unlikely]] {
812- return false;
813- }
814- }
815- // Unnamed curves can be described by their mathematical properties,
816- // but aren't used much (at all?) with X.509/TLS. Support later if
817- // needed.
818- return true;
819- })) [[unlikely]] {
820- return {};
821- }
768+ MaybeLocal<Value> values[] = {
769+ GetX509NameObject(env, cert.getSubjectName()),
770+ GetX509NameObject(env, cert.getIssuerName()),
771+ GetSubjectAltNameString(env, cert),
772+ GetInfoAccessString(env, cert),
773+ Boolean::New(env->isolate(), cert.isCA()),
774+ Undefined(env->isolate()), // modulus
775+ Undefined(env->isolate()), // exponent
776+ Undefined(env->isolate()), // pubkey
777+ Undefined(env->isolate()), // bits
778+ GetValidFrom(env, cert),
779+ GetValidTo(env, cert),
780+ GetFingerprintDigest(env, Digest::SHA1, cert),
781+ GetFingerprintDigest(env, Digest::SHA256, cert),
782+ GetFingerprintDigest(env, Digest::SHA512, cert),
783+ GetKeyUsage(env, cert),
784+ GetSerialNumber(env, cert),
785+ GetDer(env, cert),
786+ Undefined(env->isolate()), // asn1curve
787+ Undefined(env->isolate()), // nistcurve
788+ };
789+
790+ cert.ifRsa([&](const ncrypto::Rsa& rsa) {
791+ auto pub_key = rsa.getPublicKey();
792+ values[5] = GetModulusString(env, pub_key.n); // modulus
793+ values[6] = GetExponentString(env, pub_key.e); // exponent
794+ values[7] = GetPubKey(env, rsa); // pubkey
795+ values[8] = Integer::New(env->isolate(),
796+ BignumPointer::GetBitCount(pub_key.n)); // bits
797+ // TODO(@jasnell): The true response is a left-over from the original
798+ // non DictionaryTemplate-based implementation. It can be removed later.
799+ return true;
800+ });
822801
823- if (!Set<Value>(
824- env, info, env->valid_from_string(), GetValidFrom(env, cert)) ||
825- !Set<Value>(env, info, env->valid_to_string(), GetValidTo(env, cert)) ||
826- !Set<Value>(env,
827- info,
828- env->fingerprint_string(),
829- GetFingerprintDigest(env, Digest::SHA1, cert)) ||
830- !Set<Value>(env,
831- info,
832- env->fingerprint256_string(),
833- GetFingerprintDigest(env, Digest::SHA256, cert)) ||
834- !Set<Value>(env,
835- info,
836- env->fingerprint512_string(),
837- GetFingerprintDigest(env, Digest::SHA512, cert)) ||
838- !Set<Value>(
839- env, info, env->ext_key_usage_string(), GetKeyUsage(env, cert)) ||
840- !Set<Value>(
841- env, info, env->serial_number_string(), GetSerialNumber(env, cert)) ||
842- !Set<Value>(env, info, env->raw_string(), GetDer(env, cert)))
843- [[unlikely]] {
844- return {};
845- }
802+ cert.ifEc([&](const ncrypto::Ec& ec) {
803+ const auto group = ec.getGroup();
804+ values[7] = GetECPubKey(env, group, ec); // pubkey
805+ values[8] = GetECGroupBits(env, group); // bits
806+ const int nid = ec.getCurve();
807+ if (nid != 0) {
808+ // Curve is well-known, get its OID and NIST nick-name (if it has
809+ // one).
810+ values[17] = GetCurveName<OBJ_nid2sn>(env, nid); // asn1curve
811+ values[18] = GetCurveName<EC_curve_nid2nist>(env, nid); // nistcurve
812+ }
813+ // Unnamed curves can be described by their mathematical properties,
814+ // but aren't used much (at all?) with X.509/TLS. Support later if
815+ // needed.
816+ return true;
817+ });
846818
847- return scope.Escape(info );
819+ return scope.EscapeMaybe(NewDictionaryInstance(env->context(), tmpl, values) );
848820}
849821} // namespace
850822
0 commit comments