@@ -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