Skip to content

Commit 7b1f097

Browse files
committed
src: cleanup crypto for ncrypto more
1 parent 6a8f7ed commit 7b1f097

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);
@@ -2273,15 +2324,26 @@ Result<BIOPointer, bool> EVPKeyPointer::writePublicKey(
22732324
}
22742325

22752326
bool EVPKeyPointer::isRsaVariant() const {
2327+
if (!pkey_) return false;
22762328
int type = id();
2277-
return type == EVP_PKEY_RSA ||
2278-
type == EVP_PKEY_RSA2 ||
2329+
return type == EVP_PKEY_RSA || type == EVP_PKEY_RSA2 ||
22792330
type == EVP_PKEY_RSA_PSS;
22802331
}
22812332

2333+
bool EVPKeyPointer::isOneShotVariant() const {
2334+
if (!pkey_) return false;
2335+
int type = id();
2336+
return type == EVP_PKEY_ED25519 || type == EVP_PKEY_ED448;
2337+
}
2338+
2339+
bool EVPKeyPointer::isSigVariant() const {
2340+
if (!pkey_) return false;
2341+
int type = id();
2342+
return type == EVP_PKEY_EC || type == EVP_PKEY_DSA;
2343+
}
2344+
22822345
int EVPKeyPointer::getDefaultSignPadding() const {
2283-
return id() == EVP_PKEY_RSA_PSS ? RSA_PKCS1_PSS_PADDING
2284-
: RSA_PKCS1_PADDING;
2346+
return id() == EVP_PKEY_RSA_PSS ? RSA_PKCS1_PSS_PADDING : RSA_PKCS1_PADDING;
22852347
}
22862348

22872349
std::optional<uint32_t> EVPKeyPointer::getBytesOfRS() const {
@@ -2317,6 +2379,28 @@ EVPKeyPointer::operator Rsa() const {
23172379
return Rsa(rsa);
23182380
}
23192381

2382+
bool EVPKeyPointer::validateDsaParameters() const {
2383+
if (!pkey_) return false;
2384+
/* Validate DSA2 parameters from FIPS 186-4 */
2385+
#if OPENSSL_VERSION_MAJOR >= 3
2386+
if (EVP_default_properties_is_fips_enabled(nullptr) && EVP_PKEY_DSA == id()) {
2387+
#else
2388+
if (FIPS_mode() && EVP_PKEY_DSA == id()) {
2389+
#endif
2390+
const DSA* dsa = EVP_PKEY_get0_DSA(pkey_.get());
2391+
const BIGNUM* p;
2392+
const BIGNUM* q;
2393+
DSA_get0_pqg(dsa, &p, &q, nullptr);
2394+
int L = BignumPointer::GetBitCount(p);
2395+
int N = BignumPointer::GetBitCount(q);
2396+
2397+
return (L == 1024 && N == 160) || (L == 2048 && N == 224) ||
2398+
(L == 2048 && N == 256) || (L == 3072 && N == 256);
2399+
}
2400+
2401+
return true;
2402+
}
2403+
23202404
// ============================================================================
23212405

23222406
SSLPointer::SSLPointer(SSL* ssl) : ssl_(ssl) {}
@@ -3189,6 +3273,42 @@ bool EVPKeyCtxPointer::privateCheck() const {
31893273
return EVP_PKEY_check(ctx_.get()) == 1;
31903274
}
31913275

3276+
bool EVPKeyCtxPointer::verify(const Buffer<const unsigned char>& sig,
3277+
const Buffer<const unsigned char>& data) {
3278+
if (!ctx_) return false;
3279+
return EVP_PKEY_verify(ctx_.get(), sig.data, sig.len, data.data, data.len) ==
3280+
1;
3281+
}
3282+
3283+
DataPointer EVPKeyCtxPointer::sign(const Buffer<const unsigned char>& data) {
3284+
if (!ctx_) return {};
3285+
size_t len = 0;
3286+
if (EVP_PKEY_sign(ctx_.get(), nullptr, &len, data.data, data.len) != 1) {
3287+
return {};
3288+
}
3289+
auto buf = DataPointer::Alloc(len);
3290+
if (!buf) return {};
3291+
if (EVP_PKEY_sign(ctx_.get(),
3292+
static_cast<unsigned char*>(buf.get()),
3293+
&len,
3294+
data.data,
3295+
data.len) != 1) {
3296+
return {};
3297+
}
3298+
return buf.resize(len);
3299+
}
3300+
3301+
bool EVPKeyCtxPointer::signInto(const Buffer<const unsigned char>& data,
3302+
Buffer<unsigned char>* sig) {
3303+
if (!ctx_) return false;
3304+
size_t len = sig->len;
3305+
if (EVP_PKEY_sign(ctx_.get(), sig->data, &len, data.data, data.len) != 1) {
3306+
return false;
3307+
}
3308+
sig->len = len;
3309+
return true;
3310+
}
3311+
31923312
// ============================================================================
31933313

31943314
namespace {
@@ -3417,6 +3537,20 @@ DataPointer Cipher::recover(const EVPKeyPointer& key,
34173537

34183538
// ============================================================================
34193539

3540+
Ec::Ec() : ec_(nullptr) {}
3541+
3542+
Ec::Ec(const EC_KEY* key) : ec_(key) {}
3543+
3544+
const EC_GROUP* Ec::getGroup() const {
3545+
return ECKeyPointer::GetGroup(ec_);
3546+
}
3547+
3548+
int Ec::getCurve() const {
3549+
return EC_GROUP_get_curve_name(getGroup());
3550+
}
3551+
3552+
// ============================================================================
3553+
34203554
EVPMDCtxPointer::EVPMDCtxPointer() : ctx_(nullptr) {}
34213555

34223556
EVPMDCtxPointer::EVPMDCtxPointer(EVP_MD_CTX* ctx) : ctx_(ctx) {}
@@ -3429,9 +3563,13 @@ EVPMDCtxPointer& EVPMDCtxPointer::operator=(EVPMDCtxPointer&& other) noexcept {
34293563
return *this;
34303564
}
34313565

3432-
EVPMDCtxPointer::~EVPMDCtxPointer() { reset(); }
3566+
EVPMDCtxPointer::~EVPMDCtxPointer() {
3567+
reset();
3568+
}
34333569

3434-
void EVPMDCtxPointer::reset(EVP_MD_CTX* ctx) { ctx_.reset(ctx); }
3570+
void EVPMDCtxPointer::reset(EVP_MD_CTX* ctx) {
3571+
ctx_.reset(ctx);
3572+
}
34353573

34363574
EVP_MD_CTX* EVPMDCtxPointer::release() {
34373575
return ctx_.release();
@@ -3452,18 +3590,31 @@ DataPointer EVPMDCtxPointer::digestFinal(size_t length) {
34523590

34533591
auto buf = DataPointer::Alloc(length);
34543592
if (!buf) return {};
3455-
auto ptr = static_cast<unsigned char*>(buf.get());
34563593

3457-
int ret =
3458-
(length == getExpectedSize())
3459-
? EVP_DigestFinal_ex(ctx_.get(), ptr, nullptr)
3460-
: EVP_DigestFinalXOF(ctx_.get(), ptr, length);
3594+
Buffer<void> buffer = buf;
34613595

3462-
if (ret != 1) [[unlikely]] return {};
3596+
if (!digestFinalInto(&buffer)) [[unlikely]] {
3597+
return {};
3598+
}
34633599

34643600
return buf;
34653601
}
34663602

3603+
bool EVPMDCtxPointer::digestFinalInto(Buffer<void>* buf) {
3604+
if (!ctx_) false;
3605+
3606+
auto ptr = static_cast<unsigned char*>(buf->data);
3607+
3608+
int ret = (buf->len == getExpectedSize())
3609+
? EVP_DigestFinal_ex(ctx_.get(), ptr, nullptr)
3610+
: EVP_DigestFinalXOF(ctx_.get(), ptr, buf->len);
3611+
3612+
if (ret != 1) [[unlikely]]
3613+
return false;
3614+
3615+
return true;
3616+
}
3617+
34673618
size_t EVPMDCtxPointer::getExpectedSize() {
34683619
if (!ctx_) return 0;
34693620
return EVP_MD_CTX_size(ctx_.get());
@@ -3484,13 +3635,90 @@ bool EVPMDCtxPointer::hasXofFlag() const {
34843635
}
34853636

34863637
bool EVPMDCtxPointer::copyTo(const EVPMDCtxPointer& other) const {
3487-
if (!ctx_ ||!other) return {};
3638+
if (!ctx_ || !other) return {};
34883639
if (EVP_MD_CTX_copy(other.get(), ctx_.get()) != 1) return false;
34893640
return true;
34903641
}
34913642

3643+
std::optional<EVP_PKEY_CTX*> EVPMDCtxPointer::signInit(const EVPKeyPointer& key,
3644+
const EVP_MD* digest) {
3645+
EVP_PKEY_CTX* ctx = nullptr;
3646+
if (!EVP_DigestSignInit(ctx_.get(), &ctx, digest, nullptr, key.get())) {
3647+
return std::nullopt;
3648+
}
3649+
return ctx;
3650+
}
3651+
3652+
std::optional<EVP_PKEY_CTX*> EVPMDCtxPointer::verifyInit(
3653+
const EVPKeyPointer& key, const EVP_MD* digest) {
3654+
EVP_PKEY_CTX* ctx = nullptr;
3655+
if (!EVP_DigestVerifyInit(ctx_.get(), &ctx, digest, nullptr, key.get())) {
3656+
return std::nullopt;
3657+
}
3658+
return ctx;
3659+
}
3660+
3661+
DataPointer EVPMDCtxPointer::signOneShot(
3662+
const Buffer<const unsigned char>& buf) const {
3663+
if (!ctx_) return {};
3664+
size_t len;
3665+
if (!EVP_DigestSign(ctx_.get(), nullptr, &len, buf.data, buf.len)) {
3666+
return {};
3667+
}
3668+
auto data = DataPointer::Alloc(len);
3669+
if (!data) [[unlikely]]
3670+
return {};
3671+
3672+
if (!EVP_DigestSign(ctx_.get(),
3673+
static_cast<unsigned char*>(data.get()),
3674+
&len,
3675+
buf.data,
3676+
buf.len)) {
3677+
return {};
3678+
}
3679+
return data;
3680+
}
3681+
3682+
DataPointer EVPMDCtxPointer::sign(
3683+
const Buffer<const unsigned char>& buf) const {
3684+
if (!ctx_) [[unlikely]]
3685+
return {};
3686+
size_t len;
3687+
if (!EVP_DigestSignUpdate(ctx_.get(), buf.data, buf.len) ||
3688+
!EVP_DigestSignFinal(ctx_.get(), nullptr, &len)) {
3689+
return {};
3690+
}
3691+
auto data = DataPointer::Alloc(len);
3692+
if (!data) [[unlikely]]
3693+
return {};
3694+
if (!EVP_DigestSignFinal(
3695+
ctx_.get(), static_cast<unsigned char*>(data.get()), &len)) {
3696+
return {};
3697+
}
3698+
return data.resize(len);
3699+
}
3700+
3701+
bool EVPMDCtxPointer::verify(const Buffer<const unsigned char>& buf,
3702+
const Buffer<const unsigned char>& sig) const {
3703+
if (!ctx_) return false;
3704+
int ret = EVP_DigestVerify(ctx_.get(), sig.data, sig.len, buf.data, buf.len);
3705+
return ret == 1;
3706+
}
3707+
34923708
EVPMDCtxPointer EVPMDCtxPointer::New() {
34933709
return EVPMDCtxPointer(EVP_MD_CTX_new());
34943710
}
34953711

3712+
// ============================================================================
3713+
3714+
bool extractP1363(const Buffer<const unsigned char>& buf,
3715+
unsigned char* dest,
3716+
size_t n) {
3717+
auto asn1_sig = ECDSASigPointer::Parse(buf);
3718+
if (!asn1_sig) return false;
3719+
3720+
return BignumPointer::EncodePaddedInto(asn1_sig.r(), dest, n) > 0 &&
3721+
BignumPointer::EncodePaddedInto(asn1_sig.s(), dest + n, n) > 0;
3722+
}
3723+
34963724
} // namespace ncrypto

0 commit comments

Comments
 (0)