Skip to content

Commit defd263

Browse files
committed
src: cleanup crypto for ncrypto more
1 parent 21ca118 commit defd263

19 files changed

+722
-551
lines changed

deps/ncrypto/ncrypto.cc

Lines changed: 241 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,11 @@ DataPointer::~DataPointer() {
128128
reset();
129129
}
130130

131+
void DataPointer::zero() {
132+
if (!data_) return;
133+
OPENSSL_cleanse(data_, len_);
134+
}
135+
131136
void DataPointer::reset(void* data, size_t length) {
132137
if (data_ != nullptr) {
133138
OPENSSL_clear_free(data_, len_);
@@ -1160,6 +1165,52 @@ Result<X509Pointer, int> X509Pointer::Parse(
11601165
return Result<X509Pointer, int>(ERR_get_error());
11611166
}
11621167

1168+
bool X509View::enumUsages(UsageCallback callback) const {
1169+
if (cert_ == nullptr) return false;
1170+
StackOfASN1 eku(static_cast<STACK_OF(ASN1_OBJECT)*>(
1171+
X509_get_ext_d2i(cert_, NID_ext_key_usage, nullptr, nullptr)));
1172+
if (!eku) return false;
1173+
const int count = sk_ASN1_OBJECT_num(eku.get());
1174+
char buf[256]{};
1175+
1176+
int j = 0;
1177+
for (int i = 0; i < count; i++) {
1178+
if (OBJ_obj2txt(buf, sizeof(buf), sk_ASN1_OBJECT_value(eku.get(), i), 1) >=
1179+
0) {
1180+
callback(buf);
1181+
}
1182+
}
1183+
return true;
1184+
}
1185+
1186+
bool X509View::ifRsa(KeyCallback<Rsa> callback) const {
1187+
if (cert_ == nullptr) return true;
1188+
OSSL3_CONST EVP_PKEY* pkey = X509_get0_pubkey(cert_);
1189+
OSSL3_CONST RSA* rsa = nullptr;
1190+
auto id = EVP_PKEY_id(pkey);
1191+
if (id == EVP_PKEY_RSA || id == EVP_PKEY_RSA2 || id == EVP_PKEY_RSA_PSS) {
1192+
Rsa rsa(EVP_PKEY_get0_RSA(pkey));
1193+
if (!rsa) [[unlikely]]
1194+
return true;
1195+
return callback(rsa);
1196+
}
1197+
return true;
1198+
}
1199+
1200+
bool X509View::ifEc(KeyCallback<Ec> callback) const {
1201+
if (cert_ == nullptr) return true;
1202+
OSSL3_CONST EVP_PKEY* pkey = X509_get0_pubkey(cert_);
1203+
OSSL3_CONST EC_KEY* ec = nullptr;
1204+
auto id = EVP_PKEY_id(pkey);
1205+
if (id == EVP_PKEY_EC) {
1206+
Ec ec(EVP_PKEY_get0_EC_KEY(pkey));
1207+
if (!ec) [[unlikely]]
1208+
return true;
1209+
return callback(ec);
1210+
}
1211+
return true;
1212+
}
1213+
11631214
X509Pointer X509Pointer::IssuerFrom(const SSLPointer& ssl,
11641215
const X509View& view) {
11651216
return IssuerFrom(SSL_get_SSL_CTX(ssl.get()), view);
@@ -2287,15 +2338,26 @@ Result<BIOPointer, bool> EVPKeyPointer::writePublicKey(
22872338
}
22882339

22892340
bool EVPKeyPointer::isRsaVariant() const {
2341+
if (!pkey_) return false;
22902342
int type = id();
2291-
return type == EVP_PKEY_RSA ||
2292-
type == EVP_PKEY_RSA2 ||
2343+
return type == EVP_PKEY_RSA || type == EVP_PKEY_RSA2 ||
22932344
type == EVP_PKEY_RSA_PSS;
22942345
}
22952346

2347+
bool EVPKeyPointer::isOneShotVariant() const {
2348+
if (!pkey_) return false;
2349+
int type = id();
2350+
return type == EVP_PKEY_ED25519 || type == EVP_PKEY_ED448;
2351+
}
2352+
2353+
bool EVPKeyPointer::isSigVariant() const {
2354+
if (!pkey_) return false;
2355+
int type = id();
2356+
return type == EVP_PKEY_EC || type == EVP_PKEY_DSA;
2357+
}
2358+
22962359
int EVPKeyPointer::getDefaultSignPadding() const {
2297-
return id() == EVP_PKEY_RSA_PSS ? RSA_PKCS1_PSS_PADDING
2298-
: RSA_PKCS1_PADDING;
2360+
return id() == EVP_PKEY_RSA_PSS ? RSA_PKCS1_PSS_PADDING : RSA_PKCS1_PADDING;
22992361
}
23002362

23012363
std::optional<uint32_t> EVPKeyPointer::getBytesOfRS() const {
@@ -2331,6 +2393,28 @@ EVPKeyPointer::operator Rsa() const {
23312393
return Rsa(rsa);
23322394
}
23332395

2396+
bool EVPKeyPointer::validateDsaParameters() const {
2397+
if (!pkey_) return false;
2398+
/* Validate DSA2 parameters from FIPS 186-4 */
2399+
#if OPENSSL_VERSION_MAJOR >= 3
2400+
if (EVP_default_properties_is_fips_enabled(nullptr) && EVP_PKEY_DSA == id()) {
2401+
#else
2402+
if (FIPS_mode() && EVP_PKEY_DSA == id()) {
2403+
#endif
2404+
const DSA* dsa = EVP_PKEY_get0_DSA(pkey_.get());
2405+
const BIGNUM* p;
2406+
const BIGNUM* q;
2407+
DSA_get0_pqg(dsa, &p, &q, nullptr);
2408+
int L = BignumPointer::GetBitCount(p);
2409+
int N = BignumPointer::GetBitCount(q);
2410+
2411+
return (L == 1024 && N == 160) || (L == 2048 && N == 224) ||
2412+
(L == 2048 && N == 256) || (L == 3072 && N == 256);
2413+
}
2414+
2415+
return true;
2416+
}
2417+
23342418
// ============================================================================
23352419

23362420
SSLPointer::SSLPointer(SSL* ssl) : ssl_(ssl) {}
@@ -3203,6 +3287,42 @@ bool EVPKeyCtxPointer::privateCheck() const {
32033287
return EVP_PKEY_check(ctx_.get()) == 1;
32043288
}
32053289

3290+
bool EVPKeyCtxPointer::verify(const Buffer<const unsigned char>& sig,
3291+
const Buffer<const unsigned char>& data) {
3292+
if (!ctx_) return false;
3293+
return EVP_PKEY_verify(ctx_.get(), sig.data, sig.len, data.data, data.len) ==
3294+
1;
3295+
}
3296+
3297+
DataPointer EVPKeyCtxPointer::sign(const Buffer<const unsigned char>& data) {
3298+
if (!ctx_) return {};
3299+
size_t len = 0;
3300+
if (EVP_PKEY_sign(ctx_.get(), nullptr, &len, data.data, data.len) != 1) {
3301+
return {};
3302+
}
3303+
auto buf = DataPointer::Alloc(len);
3304+
if (!buf) return {};
3305+
if (EVP_PKEY_sign(ctx_.get(),
3306+
static_cast<unsigned char*>(buf.get()),
3307+
&len,
3308+
data.data,
3309+
data.len) != 1) {
3310+
return {};
3311+
}
3312+
return buf.resize(len);
3313+
}
3314+
3315+
bool EVPKeyCtxPointer::signInto(const Buffer<const unsigned char>& data,
3316+
Buffer<unsigned char>* sig) {
3317+
if (!ctx_) return false;
3318+
size_t len = sig->len;
3319+
if (EVP_PKEY_sign(ctx_.get(), sig->data, &len, data.data, data.len) != 1) {
3320+
return false;
3321+
}
3322+
sig->len = len;
3323+
return true;
3324+
}
3325+
32063326
// ============================================================================
32073327

32083328
namespace {
@@ -3431,6 +3551,20 @@ DataPointer Cipher::recover(const EVPKeyPointer& key,
34313551

34323552
// ============================================================================
34333553

3554+
Ec::Ec() : ec_(nullptr) {}
3555+
3556+
Ec::Ec(const EC_KEY* key) : ec_(key) {}
3557+
3558+
const EC_GROUP* Ec::getGroup() const {
3559+
return ECKeyPointer::GetGroup(ec_);
3560+
}
3561+
3562+
int Ec::getCurve() const {
3563+
return EC_GROUP_get_curve_name(getGroup());
3564+
}
3565+
3566+
// ============================================================================
3567+
34343568
EVPMDCtxPointer::EVPMDCtxPointer() : ctx_(nullptr) {}
34353569

34363570
EVPMDCtxPointer::EVPMDCtxPointer(EVP_MD_CTX* ctx) : ctx_(ctx) {}
@@ -3443,9 +3577,13 @@ EVPMDCtxPointer& EVPMDCtxPointer::operator=(EVPMDCtxPointer&& other) noexcept {
34433577
return *this;
34443578
}
34453579

3446-
EVPMDCtxPointer::~EVPMDCtxPointer() { reset(); }
3580+
EVPMDCtxPointer::~EVPMDCtxPointer() {
3581+
reset();
3582+
}
34473583

3448-
void EVPMDCtxPointer::reset(EVP_MD_CTX* ctx) { ctx_.reset(ctx); }
3584+
void EVPMDCtxPointer::reset(EVP_MD_CTX* ctx) {
3585+
ctx_.reset(ctx);
3586+
}
34493587

34503588
EVP_MD_CTX* EVPMDCtxPointer::release() {
34513589
return ctx_.release();
@@ -3466,18 +3604,31 @@ DataPointer EVPMDCtxPointer::digestFinal(size_t length) {
34663604

34673605
auto buf = DataPointer::Alloc(length);
34683606
if (!buf) return {};
3469-
auto ptr = static_cast<unsigned char*>(buf.get());
34703607

3471-
int ret =
3472-
(length == getExpectedSize())
3473-
? EVP_DigestFinal_ex(ctx_.get(), ptr, nullptr)
3474-
: EVP_DigestFinalXOF(ctx_.get(), ptr, length);
3608+
Buffer<void> buffer = buf;
34753609

3476-
if (ret != 1) [[unlikely]] return {};
3610+
if (!digestFinalInto(&buffer)) [[unlikely]] {
3611+
return {};
3612+
}
34773613

34783614
return buf;
34793615
}
34803616

3617+
bool EVPMDCtxPointer::digestFinalInto(Buffer<void>* buf) {
3618+
if (!ctx_) false;
3619+
3620+
auto ptr = static_cast<unsigned char*>(buf->data);
3621+
3622+
int ret = (buf->len == getExpectedSize())
3623+
? EVP_DigestFinal_ex(ctx_.get(), ptr, nullptr)
3624+
: EVP_DigestFinalXOF(ctx_.get(), ptr, buf->len);
3625+
3626+
if (ret != 1) [[unlikely]]
3627+
return false;
3628+
3629+
return true;
3630+
}
3631+
34813632
size_t EVPMDCtxPointer::getExpectedSize() {
34823633
if (!ctx_) return 0;
34833634
return EVP_MD_CTX_size(ctx_.get());
@@ -3498,13 +3649,90 @@ bool EVPMDCtxPointer::hasXofFlag() const {
34983649
}
34993650

35003651
bool EVPMDCtxPointer::copyTo(const EVPMDCtxPointer& other) const {
3501-
if (!ctx_ ||!other) return {};
3652+
if (!ctx_ || !other) return {};
35023653
if (EVP_MD_CTX_copy(other.get(), ctx_.get()) != 1) return false;
35033654
return true;
35043655
}
35053656

3657+
std::optional<EVP_PKEY_CTX*> EVPMDCtxPointer::signInit(const EVPKeyPointer& key,
3658+
const EVP_MD* digest) {
3659+
EVP_PKEY_CTX* ctx = nullptr;
3660+
if (!EVP_DigestSignInit(ctx_.get(), &ctx, digest, nullptr, key.get())) {
3661+
return std::nullopt;
3662+
}
3663+
return ctx;
3664+
}
3665+
3666+
std::optional<EVP_PKEY_CTX*> EVPMDCtxPointer::verifyInit(
3667+
const EVPKeyPointer& key, const EVP_MD* digest) {
3668+
EVP_PKEY_CTX* ctx = nullptr;
3669+
if (!EVP_DigestVerifyInit(ctx_.get(), &ctx, digest, nullptr, key.get())) {
3670+
return std::nullopt;
3671+
}
3672+
return ctx;
3673+
}
3674+
3675+
DataPointer EVPMDCtxPointer::signOneShot(
3676+
const Buffer<const unsigned char>& buf) const {
3677+
if (!ctx_) return {};
3678+
size_t len;
3679+
if (!EVP_DigestSign(ctx_.get(), nullptr, &len, buf.data, buf.len)) {
3680+
return {};
3681+
}
3682+
auto data = DataPointer::Alloc(len);
3683+
if (!data) [[unlikely]]
3684+
return {};
3685+
3686+
if (!EVP_DigestSign(ctx_.get(),
3687+
static_cast<unsigned char*>(data.get()),
3688+
&len,
3689+
buf.data,
3690+
buf.len)) {
3691+
return {};
3692+
}
3693+
return data;
3694+
}
3695+
3696+
DataPointer EVPMDCtxPointer::sign(
3697+
const Buffer<const unsigned char>& buf) const {
3698+
if (!ctx_) [[unlikely]]
3699+
return {};
3700+
size_t len;
3701+
if (!EVP_DigestSignUpdate(ctx_.get(), buf.data, buf.len) ||
3702+
!EVP_DigestSignFinal(ctx_.get(), nullptr, &len)) {
3703+
return {};
3704+
}
3705+
auto data = DataPointer::Alloc(len);
3706+
if (!data) [[unlikely]]
3707+
return {};
3708+
if (!EVP_DigestSignFinal(
3709+
ctx_.get(), static_cast<unsigned char*>(data.get()), &len)) {
3710+
return {};
3711+
}
3712+
return data.resize(len);
3713+
}
3714+
3715+
bool EVPMDCtxPointer::verify(const Buffer<const unsigned char>& buf,
3716+
const Buffer<const unsigned char>& sig) const {
3717+
if (!ctx_) return false;
3718+
int ret = EVP_DigestVerify(ctx_.get(), sig.data, sig.len, buf.data, buf.len);
3719+
return ret == 1;
3720+
}
3721+
35063722
EVPMDCtxPointer EVPMDCtxPointer::New() {
35073723
return EVPMDCtxPointer(EVP_MD_CTX_new());
35083724
}
35093725

3726+
// ============================================================================
3727+
3728+
bool extractP1363(const Buffer<const unsigned char>& buf,
3729+
unsigned char* dest,
3730+
size_t n) {
3731+
auto asn1_sig = ECDSASigPointer::Parse(buf);
3732+
if (!asn1_sig) return false;
3733+
3734+
return BignumPointer::EncodePaddedInto(asn1_sig.r(), dest, n) > 0 &&
3735+
BignumPointer::EncodePaddedInto(asn1_sig.s(), dest + n, n) > 0;
3736+
}
3737+
35103738
} // namespace ncrypto

0 commit comments

Comments
 (0)