Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

src: more ncrypto #56792

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 130 additions & 2 deletions deps/ncrypto/ncrypto.cc
Original file line number Diff line number Diff line change
Expand Up @@ -915,6 +915,18 @@ BIOPointer X509View::toDER() const {
return bio;
}

const X509Name X509View::getSubjectName() const {
ClearErrorOnReturn clearErrorOnReturn;
if (cert_ == nullptr) return {};
return X509Name(X509_get_subject_name(cert_));
}

const X509Name X509View::getIssuerName() const {
ClearErrorOnReturn clearErrorOnReturn;
if (cert_ == nullptr) return {};
return X509Name(X509_get_issuer_name(cert_));
}

BIOPointer X509View::getSubject() const {
ClearErrorOnReturn clearErrorOnReturn;
if (cert_ == nullptr) return {};
Expand Down Expand Up @@ -2390,6 +2402,15 @@ EVPKeyPointer::operator Rsa() const {
return Rsa(rsa);
}

EVPKeyPointer::operator Dsa() const {
int type = id();
if (type != EVP_PKEY_DSA) return {};

OSSL3_CONST DSA* dsa = EVP_PKEY_get0_DSA(get());
if (dsa == nullptr) return {};
return Dsa(dsa);
}

bool EVPKeyPointer::validateDsaParameters() const {
if (!pkey_) return false;
/* Validate DSA2 parameters from FIPS 186-4 */
Expand Down Expand Up @@ -2585,6 +2606,24 @@ EVPKeyPointer SSLPointer::getPeerTempKey() const {
return EVPKeyPointer(raw_key);
}

std::optional<std::string_view> SSLPointer::getCipherName() const {
auto cipher = getCipher();
if (cipher == nullptr) return std::nullopt;
return SSL_CIPHER_get_name(cipher);
}

std::optional<std::string_view> SSLPointer::getCipherStandardName() const {
auto cipher = getCipher();
if (cipher == nullptr) return std::nullopt;
return SSL_CIPHER_standard_name(cipher);
}

std::optional<std::string_view> SSLPointer::getCipherVersion() const {
auto cipher = getCipher();
if (cipher == nullptr) return std::nullopt;
return SSL_CIPHER_get_version(cipher);
}

SSLCtxPointer::SSLCtxPointer(SSL_CTX* ctx) : ctx_(ctx) {}

SSLCtxPointer::SSLCtxPointer(SSLCtxPointer&& other) noexcept
Expand Down Expand Up @@ -2630,8 +2669,8 @@ bool SSLCtxPointer::setGroups(const char* groups) {

// ============================================================================

const Cipher Cipher::FromName(const char* name) {
return Cipher(EVP_get_cipherbyname(name));
const Cipher Cipher::FromName(std::string_view name) {
return Cipher(EVP_get_cipherbyname(name.data()));
}

const Cipher Cipher::FromNid(int nid) {
Expand Down Expand Up @@ -3813,4 +3852,93 @@ DataPointer hashDigest(const Buffer<const unsigned char>& buf,
return data.resize(result_size);
}

// ============================================================================

X509Name::X509Name() : name_(nullptr), total_(0) {}
jasnell marked this conversation as resolved.
Show resolved Hide resolved

X509Name::X509Name(const X509_NAME* name)
: name_(name), total_(X509_NAME_entry_count(name)) {}

X509Name::Iterator::Iterator(const X509Name& name, int pos)
: name_(name), loc_(pos) {}

X509Name::Iterator& X509Name::Iterator::operator++() {
++loc_;
return *this;
}

X509Name::Iterator::operator bool() const {
jasnell marked this conversation as resolved.
Show resolved Hide resolved
return loc_ < name_.total_;
}

bool X509Name::Iterator::operator==(const Iterator& other) const {
return loc_ == other.loc_;
}

bool X509Name::Iterator::operator!=(const Iterator& other) const {
return loc_ != other.loc_;
}

std::pair<std::string, std::string> X509Name::Iterator::operator*() const {
if (loc_ == name_.total_) return {{}, {}};

X509_NAME_ENTRY* entry = X509_NAME_get_entry(name_, loc_);
if (entry == nullptr) [[unlikely]]
return {{}, {}};

ASN1_OBJECT* name = X509_NAME_ENTRY_get_object(entry);
ASN1_STRING* value = X509_NAME_ENTRY_get_data(entry);

if (name == nullptr || value == nullptr) [[unlikely]] {
return {{}, {}};
}

int nid = OBJ_obj2nid(name);
std::string name_str;
if (nid != NID_undef) {
name_str = std::string(OBJ_nid2sn(nid));
} else {
char buf[80];
OBJ_obj2txt(buf, sizeof(buf), name, 0);
name_str = std::string(buf);
}

unsigned char* value_str;
int value_str_size = ASN1_STRING_to_UTF8(&value_str, value);

return {
std::move(name_str),
std::string(reinterpret_cast<const char*>(value_str), value_str_size)};
}

// ============================================================================

Dsa::Dsa() : dsa_(nullptr) {}

Dsa::Dsa(OSSL3_CONST DSA* dsa) : dsa_(dsa) {}

const BIGNUM* Dsa::getP() const {
if (dsa_ == nullptr) return nullptr;
const BIGNUM* p;
DSA_get0_pqg(dsa_, &p, nullptr, nullptr);
return p;
}

const BIGNUM* Dsa::getQ() const {
if (dsa_ == nullptr) return nullptr;
const BIGNUM* q;
DSA_get0_pqg(dsa_, nullptr, &q, nullptr);
return q;
}

size_t Dsa::getModulusLength() const {
if (dsa_ == nullptr) return 0;
return BignumPointer::GetBitCount(getP());
}

size_t Dsa::getDivisorLength() const {
if (dsa_ == nullptr) return 0;
return BignumPointer::GetBitCount(getQ());
}

} // namespace ncrypto
79 changes: 77 additions & 2 deletions deps/ncrypto/ncrypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ class ECDSASigPointer;
class ECGroupPointer;
class ECPointPointer;
class ECKeyPointer;
class Dsa;
class Rsa;
class Ec;

Expand Down Expand Up @@ -267,7 +268,7 @@ class Cipher final {

bool isSupportedAuthenticatedMode() const;

static const Cipher FromName(const char* name);
static const Cipher FromName(std::string_view name);
static const Cipher FromNid(int nid);
static const Cipher FromCtx(const CipherCtxPointer& ctx);

Expand All @@ -292,10 +293,35 @@ class Cipher final {
const CipherParams& params,
const Buffer<const void> in);

static constexpr bool IsValidGCMTagLength(unsigned int tag_len) {
return tag_len == 4 || tag_len == 8 || (tag_len >= 12 && tag_len <= 16);
}

private:
const EVP_CIPHER* cipher_ = nullptr;
};

// ============================================================================
// DSA

class Dsa final {
public:
Dsa();
jasnell marked this conversation as resolved.
Show resolved Hide resolved
Dsa(OSSL3_CONST DSA* dsa);
NCRYPTO_DISALLOW_COPY_AND_MOVE(Dsa)

inline operator bool() const { return dsa_ != nullptr; }
inline operator OSSL3_CONST DSA*() const { return dsa_; }

const BIGNUM* getP() const;
const BIGNUM* getQ() const;
size_t getModulusLength() const;
size_t getDivisorLength() const;

private:
OSSL3_CONST DSA* dsa_;
};

// ============================================================================
// RSA

Expand Down Expand Up @@ -384,7 +410,12 @@ class DataPointer final {

inline bool operator==(std::nullptr_t) noexcept { return data_ == nullptr; }
inline operator bool() const { return data_ != nullptr; }
inline void* get() const noexcept { return data_; }

template <typename T = void>
inline T* get() const noexcept {
return static_cast<T*>(data_);
}

inline size_t size() const noexcept { return len_; }
void reset(void* data = nullptr, size_t len = 0);
void reset(const Buffer<void>& buffer);
Expand Down Expand Up @@ -762,6 +793,7 @@ class EVPKeyPointer final {
std::optional<uint32_t> getBytesOfRS() const;
int getDefaultSignPadding() const;
operator Rsa() const;
operator Dsa() const;

bool isRsaVariant() const;
bool isOneShotVariant() const;
Expand Down Expand Up @@ -914,6 +946,10 @@ class SSLPointer final {
const SSL_CIPHER* getCipher() const;
bool isServer() const;

std::optional<std::string_view> getCipherName() const;
std::optional<std::string_view> getCipherStandardName() const;
std::optional<std::string_view> getCipherVersion() const;

std::optional<uint32_t> verifyPeerCertificate() const;

void getCiphers(std::function<void(const std::string_view)> cb) const;
Expand All @@ -925,6 +961,43 @@ class SSLPointer final {
DeleteFnPtr<SSL, SSL_free> ssl_;
};

class X509Name final {
public:
X509Name();
explicit X509Name(const X509_NAME* name);
NCRYPTO_DISALLOW_COPY_AND_MOVE(X509Name)

inline operator const X509_NAME*() const { return name_; }
inline operator bool() const { return name_ != nullptr; }
inline const X509_NAME* get() const { return name_; }
inline size_t size() const { return total_; }

class Iterator final {
public:
Iterator(const X509Name& name, int pos);
Iterator(const Iterator& other) = default;
Iterator(Iterator&& other) = default;
Iterator& operator=(const Iterator& other) = delete;
Iterator& operator=(Iterator&& other) = delete;
Iterator& operator++();
operator bool() const;
bool operator==(const Iterator& other) const;
bool operator!=(const Iterator& other) const;
std::pair<std::string, std::string> operator*() const;

private:
const X509Name& name_;
int loc_;
};

inline Iterator begin() const { return Iterator(*this, 0); }
inline Iterator end() const { return Iterator(*this, total_); }

private:
const X509_NAME* name_;
int total_;
};

class X509View final {
public:
static X509View From(const SSLPointer& ssl);
Expand All @@ -946,6 +1019,8 @@ class X509View final {
BIOPointer toPEM() const;
BIOPointer toDER() const;

const X509Name getSubjectName() const;
const X509Name getIssuerName() const;
BIOPointer getSubject() const;
BIOPointer getSubjectAltName() const;
BIOPointer getIssuer() const;
Expand Down
4 changes: 0 additions & 4 deletions src/crypto/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,6 @@ an `ArrayBuffer` (`v8::BackingStore`), or allocated data.
* If allocated data is used, then it must have been allocated using OpenSSL's
allocator. It will be freed automatically when the `ByteSource` is destroyed.

The `ByteSource::Builder` class can be used to allocate writable memory that can
then be released as a `ByteSource`, making it read-only, or freed by destroying
the `ByteSource::Builder` without releasing it as a `ByteSource`.

### `ArrayBufferOrViewContents`

The `ArrayBufferOrViewContents` class is a helper utility that abstracts
Expand Down
Loading
Loading