Skip to content

Commit e330f03

Browse files
jasnelltargos
authored andcommitted
src: update crypto objects to use DictionaryTemplate
PR-URL: #59942 Reviewed-By: Tobias Nießen <[email protected]> Reviewed-By: Anna Henningsen <[email protected]>
1 parent 0b284d8 commit e330f03

File tree

4 files changed

+126
-174
lines changed

4 files changed

+126
-174
lines changed

src/crypto/crypto_common.cc

Lines changed: 44 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ using ncrypto::X509Pointer;
3737
using ncrypto::X509View;
3838
using v8::ArrayBuffer;
3939
using v8::BackingStoreInitializationMode;
40-
using v8::Context;
40+
using v8::DictionaryTemplate;
4141
using v8::EscapableHandleScope;
4242
using v8::Integer;
4343
using v8::Local;
@@ -180,76 +180,69 @@ Local<Value> maybeString(Environment* env,
180180
MaybeLocal<Object> GetCipherInfo(Environment* env, const SSLPointer& ssl) {
181181
if (ssl.getCipher() == nullptr) return MaybeLocal<Object>();
182182
EscapableHandleScope scope(env->isolate());
183-
Local<Object> info = Object::New(env->isolate());
184-
185-
if (info->Set(env->context(),
186-
env->name_string(),
187-
maybeString(env, ssl.getCipherName()))
188-
.IsNothing() ||
189-
info->Set(env->context(),
190-
env->standard_name_string(),
191-
maybeString(env, ssl.getCipherStandardName()))
192-
.IsNothing() ||
193-
info->Set(env->context(),
194-
env->version_string(),
195-
maybeString(env, ssl.getCipherVersion()))
196-
.IsNothing()) {
197-
return MaybeLocal<Object>();
183+
184+
auto tmpl = env->cipherinfo_template();
185+
if (tmpl.IsEmpty()) {
186+
static constexpr std::string_view names[] = {
187+
"name", "standardName", "version"};
188+
tmpl = DictionaryTemplate::New(env->isolate(), names);
189+
env->set_cipherinfo_template(tmpl);
198190
}
199191

200-
return scope.Escape(info);
192+
MaybeLocal<Value> values[] = {
193+
maybeString(env, ssl.getCipherName()),
194+
maybeString(env, ssl.getCipherStandardName()),
195+
maybeString(env, ssl.getCipherVersion()),
196+
};
197+
198+
return scope.EscapeMaybe(NewDictionaryInstance(env->context(), tmpl, values));
201199
}
202200

203201
MaybeLocal<Object> GetEphemeralKey(Environment* env, const SSLPointer& ssl) {
204202
CHECK(!ssl.isServer());
205203

206204
EscapableHandleScope scope(env->isolate());
207-
Local<Object> info = Object::New(env->isolate());
205+
206+
auto tmpl = env->ephemeral_key_template();
207+
if (tmpl.IsEmpty()) {
208+
static constexpr std::string_view names[] = {"type", "name", "size"};
209+
tmpl = DictionaryTemplate::New(env->isolate(), names);
210+
env->set_ephemeral_key_template(tmpl);
211+
}
212+
213+
MaybeLocal<Value> values[] = {
214+
Undefined(env->isolate()), // type
215+
Undefined(env->isolate()), // name
216+
Undefined(env->isolate()), // size
217+
};
208218
EVPKeyPointer key = ssl.getPeerTempKey();
209-
if (!key) return scope.Escape(info);
210-
211-
Local<Context> context = env->context();
212-
213-
int kid = key.id();
214-
switch (kid) {
215-
case EVP_PKEY_DH:
216-
if (info->Set(context, env->type_string(), env->dh_string())
217-
.IsNothing() ||
218-
info->Set(context,
219-
env->size_string(),
220-
Integer::New(env->isolate(), key.bits()))
221-
.IsNothing()) {
222-
return MaybeLocal<Object>();
219+
if (EVPKeyPointer key = ssl.getPeerTempKey()) {
220+
int kid = key.id();
221+
switch (kid) {
222+
case EVP_PKEY_DH: {
223+
values[0] = env->dh_string();
224+
values[2] = Integer::New(env->isolate(), key.bits());
225+
break;
223226
}
224-
break;
225-
case EVP_PKEY_EC:
226-
case EVP_PKEY_X25519:
227-
case EVP_PKEY_X448:
228-
{
227+
case EVP_PKEY_EC:
228+
case EVP_PKEY_X25519:
229+
case EVP_PKEY_X448: {
229230
const char* curve_name;
230231
if (kid == EVP_PKEY_EC) {
231232
int nid = ECKeyPointer::GetGroupName(key);
232233
curve_name = OBJ_nid2sn(nid);
233234
} else {
234235
curve_name = OBJ_nid2sn(kid);
235236
}
236-
if (info->Set(context, env->type_string(), env->ecdh_string())
237-
.IsNothing() ||
238-
info->Set(context,
239-
env->name_string(),
240-
OneByteString(env->isolate(), curve_name))
241-
.IsNothing() ||
242-
info->Set(context,
243-
env->size_string(),
244-
Integer::New(env->isolate(), key.bits()))
245-
.IsNothing()) {
246-
return MaybeLocal<Object>();
247-
}
237+
values[0] = env->ecdh_string();
238+
values[1] = OneByteString(env->isolate(), curve_name);
239+
values[2] = Integer::New(env->isolate(), key.bits());
240+
break;
248241
}
249-
break;
242+
}
250243
}
251244

252-
return scope.Escape(info);
245+
return scope.EscapeMaybe(NewDictionaryInstance(env->context(), tmpl, values));
253246
}
254247

255248
MaybeLocal<Object> ECPointToBuffer(Environment* env,

src/crypto/crypto_x509.cc

Lines changed: 77 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ using v8::BackingStoreOnFailureMode;
3333
using v8::Boolean;
3434
using v8::Context;
3535
using v8::Date;
36+
using v8::DictionaryTemplate;
3637
using v8::EscapableHandleScope;
3738
using v8::Function;
3839
using v8::FunctionCallbackInfo;
@@ -46,6 +47,7 @@ using v8::NewStringType;
4647
using v8::Object;
4748
using v8::String;
4849
using v8::Uint32;
50+
using v8::Undefined;
4951
using v8::Value;
5052

5153
namespace crypto {
@@ -735,116 +737,86 @@ MaybeLocal<Value> GetCurveName(Environment* env, const int nid) {
735737

736738
MaybeLocal<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

Comments
 (0)