Skip to content

Commit 341ee31

Browse files
jasnelldanielleadams
authored andcommitted
crypto: reconcile duplicated code
Signed-off-by: James M Snell <jasnell@gmail.com> PR-URL: #37704 Reviewed-By: Filip Skokan <panva.ip@gmail.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
1 parent 764aa2d commit 341ee31

File tree

3 files changed

+50
-140
lines changed

3 files changed

+50
-140
lines changed

src/crypto/crypto_ec.cc

-114
Original file line numberDiff line numberDiff line change
@@ -927,119 +927,5 @@ size_t GroupOrderSize(ManagedEVPPKey key) {
927927
CHECK(EC_GROUP_get_order(group, order.get(), nullptr));
928928
return BN_num_bytes(order.get());
929929
}
930-
931-
// TODO(@jasnell): Reconcile with ConvertSignatureToP1363 in crypto_sig.cc
932-
// TODO(@jasnell): Move out of crypto_ec since this is also doing DSA now also
933-
ByteSource ConvertToWebCryptoSignature(
934-
const ManagedEVPPKey& key,
935-
const ByteSource& signature) {
936-
const unsigned char* data =
937-
reinterpret_cast<const unsigned char*>(signature.get());
938-
939-
ECDSASigPointer ecsig;
940-
DsaSigPointer dsasig;
941-
const BIGNUM* pr;
942-
const BIGNUM* ps;
943-
size_t len = 0;
944-
945-
switch (EVP_PKEY_id(key.get())) {
946-
case EVP_PKEY_EC: {
947-
ecsig = ECDSASigPointer(d2i_ECDSA_SIG(nullptr, &data, signature.size()));
948-
949-
if (!ecsig)
950-
return ByteSource();
951-
952-
len = GroupOrderSize(key);
953-
954-
ECDSA_SIG_get0(ecsig.get(), &pr, &ps);
955-
break;
956-
}
957-
case EVP_PKEY_DSA: {
958-
dsasig = DsaSigPointer(d2i_DSA_SIG(nullptr, &data, signature.size()));
959-
960-
if (!dsasig)
961-
return ByteSource();
962-
963-
DSA_SIG_get0(dsasig.get(), &pr, &ps);
964-
len = std::max(BN_num_bytes(pr), BN_num_bytes(ps));
965-
}
966-
}
967-
968-
CHECK_GT(len, 0);
969-
970-
char* outdata = MallocOpenSSL<char>(len * 2);
971-
memset(outdata, 0, len * 2);
972-
ByteSource out = ByteSource::Allocated(outdata, len * 2);
973-
unsigned char* ptr = reinterpret_cast<unsigned char*>(outdata);
974-
975-
if (BN_bn2binpad(pr, ptr, len) <= 0 ||
976-
BN_bn2binpad(ps, ptr + len, len) <= 0) {
977-
return ByteSource();
978-
}
979-
980-
return out;
981-
}
982-
983-
// TODO(@jasnell): Reconcile with ConvertSignatureToDER in crypto_sig.cc
984-
// TODO(@jasnell): Move out of crypto_ec since this is also doing DSA now also
985-
ByteSource ConvertFromWebCryptoSignature(
986-
const ManagedEVPPKey& key,
987-
const ByteSource& signature) {
988-
BignumPointer r(BN_new());
989-
BignumPointer s(BN_new());
990-
const unsigned char* sig = signature.data<unsigned char>();
991-
992-
switch (EVP_PKEY_id(key.get())) {
993-
case EVP_PKEY_EC: {
994-
size_t order_size_bytes = GroupOrderSize(key);
995-
996-
// If the size of the signature is incorrect, verification
997-
// will fail.
998-
if (signature.size() != 2 * order_size_bytes)
999-
return ByteSource(); // Empty!
1000-
1001-
ECDSASigPointer ecsig(ECDSA_SIG_new());
1002-
if (!ecsig)
1003-
return ByteSource();
1004-
1005-
if (!BN_bin2bn(sig, order_size_bytes, r.get()) ||
1006-
!BN_bin2bn(sig + order_size_bytes, order_size_bytes, s.get()) ||
1007-
!ECDSA_SIG_set0(ecsig.get(), r.release(), s.release())) {
1008-
return ByteSource();
1009-
}
1010-
1011-
int size = i2d_ECDSA_SIG(ecsig.get(), nullptr);
1012-
char* data = MallocOpenSSL<char>(size);
1013-
unsigned char* ptr = reinterpret_cast<unsigned char*>(data);
1014-
CHECK_EQ(i2d_ECDSA_SIG(ecsig.get(), &ptr), size);
1015-
return ByteSource::Allocated(data, size);
1016-
}
1017-
case EVP_PKEY_DSA: {
1018-
size_t len = signature.size() / 2;
1019-
1020-
if (signature.size() != 2 * len)
1021-
return ByteSource();
1022-
1023-
DsaSigPointer dsasig(DSA_SIG_new());
1024-
if (!dsasig)
1025-
return ByteSource();
1026-
1027-
if (!BN_bin2bn(sig, len, r.get()) ||
1028-
!BN_bin2bn(sig + len, len, s.get()) ||
1029-
!DSA_SIG_set0(dsasig.get(), r.release(), s.release())) {
1030-
return ByteSource();
1031-
}
1032-
1033-
int size = i2d_DSA_SIG(dsasig.get(), nullptr);
1034-
char* data = MallocOpenSSL<char>(size);
1035-
unsigned char* ptr = reinterpret_cast<unsigned char*>(data);
1036-
CHECK_EQ(i2d_DSA_SIG(dsasig.get(), &ptr), size);
1037-
return ByteSource::Allocated(data, size);
1038-
}
1039-
default:
1040-
UNREACHABLE();
1041-
}
1042-
}
1043-
1044930
} // namespace crypto
1045931
} // namespace node

src/crypto/crypto_ec.h

-9
Original file line numberDiff line numberDiff line change
@@ -162,15 +162,6 @@ v8::Maybe<bool> GetEcKeyDetail(
162162
Environment* env,
163163
std::shared_ptr<KeyObjectData> key,
164164
v8::Local<v8::Object> target);
165-
166-
ByteSource ConvertToWebCryptoSignature(
167-
const ManagedEVPPKey& key,
168-
const ByteSource& signature);
169-
170-
ByteSource ConvertFromWebCryptoSignature(
171-
const ManagedEVPPKey& key,
172-
const ByteSource& signature);
173-
174165
} // namespace crypto
175166
} // namespace node
176167

src/crypto/crypto_sig.cc

+50-17
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,21 @@ unsigned int GetBytesOfRS(const ManagedEVPPKey& pkey) {
117117
return (bits + 7) / 8;
118118
}
119119

120+
bool ExtractP1363(
121+
const unsigned char* sig_data,
122+
unsigned char* out,
123+
size_t len,
124+
size_t n) {
125+
ECDSASigPointer asn1_sig(d2i_ECDSA_SIG(nullptr, &sig_data, len));
126+
if (!asn1_sig)
127+
return false;
128+
129+
const BIGNUM* pr = ECDSA_SIG_get0_r(asn1_sig.get());
130+
const BIGNUM* ps = ECDSA_SIG_get0_s(asn1_sig.get());
131+
132+
return BN_bn2binpad(pr, out, n) > 0 && BN_bn2binpad(ps, out + n, n) > 0;
133+
}
134+
120135
// Returns the maximum size of each of the integers (r, s) of the DSA signature.
121136
AllocatedBuffer ConvertSignatureToP1363(Environment* env,
122137
const ManagedEVPPKey& pkey,
@@ -128,33 +143,49 @@ AllocatedBuffer ConvertSignatureToP1363(Environment* env,
128143
const unsigned char* sig_data =
129144
reinterpret_cast<unsigned char*>(signature.data());
130145

131-
ECDSASigPointer asn1_sig(d2i_ECDSA_SIG(nullptr, &sig_data, signature.size()));
132-
if (!asn1_sig)
133-
return AllocatedBuffer();
134-
135146
AllocatedBuffer buf = AllocatedBuffer::AllocateManaged(env, 2 * n);
136147
unsigned char* data = reinterpret_cast<unsigned char*>(buf.data());
137148

138-
const BIGNUM* r = ECDSA_SIG_get0_r(asn1_sig.get());
139-
const BIGNUM* s = ECDSA_SIG_get0_s(asn1_sig.get());
140-
CHECK_EQ(n, static_cast<unsigned int>(BN_bn2binpad(r, data, n)));
141-
CHECK_EQ(n, static_cast<unsigned int>(BN_bn2binpad(s, data + n, n)));
149+
if (!ExtractP1363(sig_data, data, signature.size(), n))
150+
return std::move(signature);
142151

143152
return buf;
144153
}
145154

155+
// Returns the maximum size of each of the integers (r, s) of the DSA signature.
156+
ByteSource ConvertSignatureToP1363(
157+
Environment* env,
158+
const ManagedEVPPKey& pkey,
159+
const ByteSource& signature) {
160+
unsigned int n = GetBytesOfRS(pkey);
161+
if (n == kNoDsaSignature)
162+
return ByteSource();
163+
164+
const unsigned char* sig_data =
165+
reinterpret_cast<const unsigned char*>(signature.get());
166+
167+
char* outdata = MallocOpenSSL<char>(n * 2);
168+
memset(outdata, 0, n * 2);
169+
ByteSource out = ByteSource::Allocated(outdata, n * 2);
170+
unsigned char* ptr = reinterpret_cast<unsigned char*>(outdata);
171+
172+
if (!ExtractP1363(sig_data, ptr, signature.size(), n))
173+
return ByteSource();
174+
175+
return out;
176+
}
146177

147178
ByteSource ConvertSignatureToDER(
148179
const ManagedEVPPKey& pkey,
149-
const ArrayBufferOrViewContents<char>& signature) {
180+
ByteSource&& out) {
150181
unsigned int n = GetBytesOfRS(pkey);
151182
if (n == kNoDsaSignature)
152-
return signature.ToByteSource();
183+
return std::move(out);
153184

154185
const unsigned char* sig_data =
155-
reinterpret_cast<const unsigned char*>(signature.data());
186+
reinterpret_cast<const unsigned char*>(out.get());
156187

157-
if (signature.size() != 2 * n)
188+
if (out.size() != 2 * n)
158189
return ByteSource();
159190

160191
ECDSASigPointer asn1_sig(ECDSA_SIG_new());
@@ -511,7 +542,7 @@ void Verify::VerifyFinal(const FunctionCallbackInfo<Value>& args) {
511542

512543
ByteSource signature = hbuf.ToByteSource();
513544
if (dsa_sig_enc == kSigEncP1363) {
514-
signature = ConvertSignatureToDER(pkey, hbuf);
545+
signature = ConvertSignatureToDER(pkey, hbuf.ToByteSource());
515546
if (signature.get() == nullptr)
516547
return crypto::CheckThrow(env, Error::kSignMalformedSignature);
517548
}
@@ -657,7 +688,7 @@ void Verify::VerifySync(const FunctionCallbackInfo<Value>& args) {
657688

658689
ByteSource sig_bytes = ByteSource::Foreign(sig.data(), sig.size());
659690
if (dsa_sig_enc == kSigEncP1363) {
660-
sig_bytes = ConvertSignatureToDER(key, sig);
691+
sig_bytes = ConvertSignatureToDER(key, sig.ToByteSource());
661692
if (!sig_bytes)
662693
return crypto::CheckThrow(env, SignBase::Error::kSignMalformedSignature);
663694
}
@@ -778,7 +809,7 @@ Maybe<bool> SignTraits::AdditionalConfig(
778809
Mutex::ScopedLock lock(*m_pkey.mutex());
779810
if (UseP1363Encoding(m_pkey, params->dsa_encoding)) {
780811
params->signature =
781-
ConvertFromWebCryptoSignature(m_pkey, signature.ToByteSource());
812+
ConvertSignatureToDER(m_pkey, signature.ToByteSource());
782813
} else {
783814
params->signature = mode == kCryptoJobAsync
784815
? signature.ToCopy()
@@ -874,8 +905,10 @@ bool SignTraits::DeriveBits(
874905
return false;
875906

876907
if (UseP1363Encoding(m_pkey, params.dsa_encoding)) {
877-
*out = ConvertToWebCryptoSignature(
878-
params.key->GetAsymmetricKey(), buf);
908+
*out = ConvertSignatureToP1363(
909+
env,
910+
params.key->GetAsymmetricKey(),
911+
buf);
879912
} else {
880913
buf.Resize(len);
881914
*out = std::move(buf);

0 commit comments

Comments
 (0)