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