11#include " ncrypto.h"
2+ #include < openssl/asn1.h>
23#include < openssl/bn.h>
34#include < openssl/dh.h>
45#include < openssl/evp.h>
@@ -99,7 +100,15 @@ std::optional<std::string> CryptoErrorList::pop_front() {
99100
100101// ============================================================================
101102DataPointer DataPointer::Alloc (size_t len) {
103+ #ifdef OPENSSL_IS_BORINGSSL
104+ // Boringssl does not implement OPENSSL_zalloc
105+ auto ptr = OPENSSL_malloc (len);
106+ if (ptr == nullptr ) return {};
107+ memset (ptr, 0 , len);
108+ return DataPointer (ptr, len);
109+ #else
102110 return DataPointer (OPENSSL_zalloc (len), len);
111+ #endif
103112}
104113
105114DataPointer DataPointer::Copy (const Buffer<const void >& buffer) {
@@ -218,7 +227,12 @@ BignumPointer BignumPointer::New() {
218227}
219228
220229BignumPointer BignumPointer::NewSecure () {
230+ #ifdef OPENSSL_IS_BORINGSSL
231+ // Boringssl does not implement BN_secure_new.
232+ return New ();
233+ #else
221234 return BignumPointer (BN_secure_new ());
235+ #endif
222236}
223237
224238BignumPointer& BignumPointer::operator =(BignumPointer&& other) noexcept {
@@ -492,6 +506,7 @@ constexpr int days_from_epoch(int y, unsigned m, unsigned d) {
492506 return era * 146097 + static_cast <int >(doe) - 719468 ;
493507}
494508
509+ #ifndef OPENSSL_IS_BORINGSSL
495510// tm must be in UTC
496511// using time_t causes problems on 32-bit systems and windows x64.
497512int64_t PortableTimeGM (struct tm * t) {
@@ -512,6 +527,7 @@ int64_t PortableTimeGM(struct tm* t) {
512527 t->tm_min ) +
513528 t->tm_sec ;
514529}
530+ #endif
515531
516532// ============================================================================
517533// SPKAC
@@ -822,7 +838,7 @@ bool SafeX509SubjectAltNamePrint(const BIOPointer& out, X509_EXTENSION* ext) {
822838
823839 bool ok = true ;
824840
825- for (int i = 0 ; i < sk_GENERAL_NAME_num (names); i++) {
841+ for (OPENSSL_SIZE_T i = 0 ; i < sk_GENERAL_NAME_num (names); i++) {
826842 GENERAL_NAME* gen = sk_GENERAL_NAME_value (names, i);
827843
828844 if (i != 0 ) BIO_write (out.get (), " , " , 2 );
@@ -846,7 +862,7 @@ bool SafeX509InfoAccessPrint(const BIOPointer& out, X509_EXTENSION* ext) {
846862
847863 bool ok = true ;
848864
849- for (int i = 0 ; i < sk_ACCESS_DESCRIPTION_num (descs); i++) {
865+ for (OPENSSL_SIZE_T i = 0 ; i < sk_ACCESS_DESCRIPTION_num (descs); i++) {
850866 ACCESS_DESCRIPTION* desc = sk_ACCESS_DESCRIPTION_value (descs, i);
851867
852868 if (i != 0 ) BIO_write (out.get (), " \n " , 1 );
@@ -999,15 +1015,31 @@ BIOPointer X509View::getValidTo() const {
9991015}
10001016
10011017int64_t X509View::getValidToTime () const {
1018+ #ifdef OPENSSL_IS_BORINGSSL
1019+ // Boringssl does not implement ASN1_TIME_to_tm in a public way,
1020+ // and only recently added ASN1_TIME_to_posix. Some boringssl
1021+ // users on older version may still need to patch around this
1022+ // or use a different implementation.
1023+ int64_t tp;
1024+ ASN1_TIME_to_posix (X509_get0_notAfter (cert_), &tp);
1025+ return tp;
1026+ #else
10021027 struct tm tp;
10031028 ASN1_TIME_to_tm (X509_get0_notAfter (cert_), &tp);
10041029 return PortableTimeGM (&tp);
1030+ #endif
10051031}
10061032
10071033int64_t X509View::getValidFromTime () const {
1034+ #ifdef OPENSSL_IS_BORINGSSL
1035+ int64_t tp;
1036+ ASN1_TIME_to_posix (X509_get0_notBefore (cert_), &tp);
1037+ return tp;
1038+ #else
10081039 struct tm tp;
10091040 ASN1_TIME_to_tm (X509_get0_notBefore (cert_), &tp);
10101041 return PortableTimeGM (&tp);
1042+ #endif
10111043}
10121044
10131045DataPointer X509View::getSerialNumber () const {
@@ -1324,7 +1356,12 @@ BIOPointer BIOPointer::NewMem() {
13241356}
13251357
13261358BIOPointer BIOPointer::NewSecMem () {
1359+ #ifdef OPENSSL_IS_BORINGSSL
1360+ // Boringssl does not implement the BIO_s_secmem API.
1361+ return BIOPointer (BIO_new (BIO_s_mem ()));
1362+ #else
13271363 return BIOPointer (BIO_new (BIO_s_secmem ()));
1364+ #endif
13281365}
13291366
13301367BIOPointer BIOPointer::New (const BIO_METHOD* method) {
@@ -1394,8 +1431,11 @@ BignumPointer DHPointer::FindGroup(const std::string_view name,
13941431#define V (n, p ) \
13951432 if (EqualNoCase (name, n)) return BignumPointer (p (nullptr ));
13961433 if (option != FindGroupOption::NO_SMALL_PRIMES) {
1434+ #ifndef OPENSSL_IS_BORINGSSL
1435+ // Boringssl does not support the 768 and 1024 small primes
13971436 V (" modp1" , BN_get_rfc2409_prime_768);
13981437 V (" modp2" , BN_get_rfc2409_prime_1024);
1438+ #endif
13991439 V (" modp5" , BN_get_rfc3526_prime_1536);
14001440 }
14011441 V (" modp14" , BN_get_rfc3526_prime_2048);
@@ -1467,15 +1507,22 @@ DHPointer::CheckResult DHPointer::check() {
14671507DHPointer::CheckPublicKeyResult DHPointer::checkPublicKey (
14681508 const BignumPointer& pub_key) {
14691509 ClearErrorOnReturn clearErrorOnReturn;
1470- if (!pub_key || !dh_) return DHPointer::CheckPublicKeyResult::CHECK_FAILED;
1510+ if (!pub_key || !dh_) {
1511+ return DHPointer::CheckPublicKeyResult::CHECK_FAILED;
1512+ }
14711513 int codes = 0 ;
1472- if (DH_check_pub_key (dh_.get (), pub_key.get (), &codes) != 1 )
1514+ if (DH_check_pub_key (dh_.get (), pub_key.get (), &codes) != 1 ) {
14731515 return DHPointer::CheckPublicKeyResult::CHECK_FAILED;
1516+ }
1517+ #ifndef OPENSSL_IS_BORINGSSL
1518+ // Boringssl does not define DH_CHECK_PUBKEY_TOO_SMALL or TOO_LARGE
14741519 if (codes & DH_CHECK_PUBKEY_TOO_SMALL) {
14751520 return DHPointer::CheckPublicKeyResult::TOO_SMALL;
1476- } else if (codes & DH_CHECK_PUBKEY_TOO_SMALL ) {
1521+ } else if (codes & DH_CHECK_PUBKEY_TOO_LARGE ) {
14771522 return DHPointer::CheckPublicKeyResult::TOO_LARGE;
1478- } else if (codes != 0 ) {
1523+ }
1524+ #endif
1525+ if (codes != 0 ) {
14791526 return DHPointer::CheckPublicKeyResult::INVALID;
14801527 }
14811528 return CheckPublicKeyResult::NONE;
@@ -2530,6 +2577,7 @@ std::optional<uint32_t> SSLPointer::verifyPeerCertificate() const {
25302577
25312578const std::string_view SSLPointer::getClientHelloAlpn () const {
25322579 if (ssl_ == nullptr ) return {};
2580+ #ifndef OPENSSL_IS_BORINGSSL
25332581 const unsigned char * buf;
25342582 size_t len;
25352583 size_t rem;
@@ -2546,10 +2594,15 @@ const std::string_view SSLPointer::getClientHelloAlpn() const {
25462594 len = (buf[0 ] << 8 ) | buf[1 ];
25472595 if (len + 2 != rem) return {};
25482596 return reinterpret_cast <const char *>(buf + 3 );
2597+ #else
2598+ // Boringssl doesn't have a public API for this.
2599+ return {};
2600+ #endif
25492601}
25502602
25512603const std::string_view SSLPointer::getClientHelloServerName () const {
25522604 if (ssl_ == nullptr ) return {};
2605+ #ifndef OPENSSL_IS_BORINGSSL
25532606 const unsigned char * buf;
25542607 size_t len;
25552608 size_t rem;
@@ -2569,6 +2622,10 @@ const std::string_view SSLPointer::getClientHelloServerName() const {
25692622 len = (*(buf + 3 ) << 8 ) | *(buf + 4 );
25702623 if (len + 2 > rem) return {};
25712624 return reinterpret_cast <const char *>(buf + 5 );
2625+ #else
2626+ // Boringssl doesn't have a public API for this.
2627+ return {};
2628+ #endif
25722629}
25732630
25742631std::optional<const std::string_view> SSLPointer::GetServerName (
@@ -2602,7 +2659,11 @@ bool SSLPointer::isServer() const {
26022659EVPKeyPointer SSLPointer::getPeerTempKey () const {
26032660 if (!ssl_) return {};
26042661 EVP_PKEY* raw_key = nullptr ;
2662+ #ifndef OPENSSL_IS_BORINGSSL
26052663 if (!SSL_get_peer_tmp_key (get (), &raw_key)) return {};
2664+ #else
2665+ if (!SSL_get_server_tmp_key (get (), &raw_key)) return {};
2666+ #endif
26062667 return EVPKeyPointer (raw_key);
26072668}
26082669
@@ -3167,9 +3228,15 @@ int EVPKeyCtxPointer::initForSign() {
31673228}
31683229
31693230bool EVPKeyCtxPointer::setDhParameters (int prime_size, uint32_t generator) {
3231+ #ifndef OPENSSL_IS_BORINGSSL
31703232 if (!ctx_) return false ;
31713233 return EVP_PKEY_CTX_set_dh_paramgen_prime_len (ctx_.get (), prime_size) == 1 &&
31723234 EVP_PKEY_CTX_set_dh_paramgen_generator (ctx_.get (), generator) == 1 ;
3235+ #else
3236+ // TODO(jasnell): Boringssl appears not to support this operation.
3237+ // Is there an alternative approach that Boringssl does support?
3238+ return false ;
3239+ #endif
31733240}
31743241
31753242bool EVPKeyCtxPointer::setDsaParameters (uint32_t bits,
@@ -3249,6 +3316,7 @@ bool EVPKeyCtxPointer::setRsaPssSaltlen(int salt_len) {
32493316}
32503317
32513318bool EVPKeyCtxPointer::setRsaImplicitRejection () {
3319+ #ifndef OPENSSL_IS_BORINGSSL
32523320 if (!ctx_) return false ;
32533321 return EVP_PKEY_CTX_ctrl_str (
32543322 ctx_.get (), " rsa_pkcs1_implicit_rejection" , " 1" ) > 0 ;
@@ -3259,6 +3327,11 @@ bool EVPKeyCtxPointer::setRsaImplicitRejection() {
32593327 // of how it is set. The call to set the value
32603328 // will not affect what is used since a different context is
32613329 // used in the call if the option is supported
3330+ #else
3331+ // TODO(jasnell): Boringssl appears not to support this operation.
3332+ // Is there an alternative approach that Boringssl does support?
3333+ return true ;
3334+ #endif
32623335}
32633336
32643337bool EVPKeyCtxPointer::setRsaOaepLabel (DataPointer&& data) {
@@ -3311,16 +3384,31 @@ EVPKeyPointer EVPKeyCtxPointer::paramgen() const {
33113384
33123385bool EVPKeyCtxPointer::publicCheck () const {
33133386 if (!ctx_) return false ;
3387+ #ifndef OPENSSL_IS_BORINGSSL
3388+ return EVP_PKEY_public_check (ctx_.get ()) == 1 ;
33143389#if OPENSSL_VERSION_MAJOR >= 3
33153390 return EVP_PKEY_public_check_quick (ctx_.get ()) == 1 ;
33163391#else
33173392 return EVP_PKEY_public_check (ctx_.get ()) == 1 ;
33183393#endif
3394+ #else // OPENSSL_IS_BORINGSSL
3395+ // Boringssl appears not to support this operation.
3396+ // TODO(jasnell): Is there an alternative approach that Boringssl does
3397+ // support?
3398+ return true ;
3399+ #endif
33193400}
33203401
33213402bool EVPKeyCtxPointer::privateCheck () const {
33223403 if (!ctx_) return false ;
3404+ #ifndef OPENSSL_IS_BORINGSSL
33233405 return EVP_PKEY_check (ctx_.get ()) == 1 ;
3406+ #else
3407+ // Boringssl appears not to support this operation.
3408+ // TODO(jasnell): Is there an alternative approach that Boringssl does
3409+ // support?
3410+ return true ;
3411+ #endif
33243412}
33253413
33263414bool EVPKeyCtxPointer::verify (const Buffer<const unsigned char >& sig,
0 commit comments