1
1
#include " ncrypto.h"
2
+ #include < openssl/asn1.h>
2
3
#include < openssl/bn.h>
3
4
#include < openssl/dh.h>
4
5
#include < openssl/evp.h>
@@ -99,7 +100,15 @@ std::optional<std::string> CryptoErrorList::pop_front() {
99
100
100
101
// ============================================================================
101
102
DataPointer 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
102
110
return DataPointer (OPENSSL_zalloc (len), len);
111
+ #endif
103
112
}
104
113
105
114
DataPointer DataPointer::Copy (const Buffer<const void >& buffer) {
@@ -218,7 +227,12 @@ BignumPointer BignumPointer::New() {
218
227
}
219
228
220
229
BignumPointer BignumPointer::NewSecure () {
230
+ #ifdef OPENSSL_IS_BORINGSSL
231
+ // Boringssl does not implement BN_secure_new.
232
+ return New ();
233
+ #else
221
234
return BignumPointer (BN_secure_new ());
235
+ #endif
222
236
}
223
237
224
238
BignumPointer& BignumPointer::operator =(BignumPointer&& other) noexcept {
@@ -492,6 +506,7 @@ constexpr int days_from_epoch(int y, unsigned m, unsigned d) {
492
506
return era * 146097 + static_cast <int >(doe) - 719468 ;
493
507
}
494
508
509
+ #ifndef OPENSSL_IS_BORINGSSL
495
510
// tm must be in UTC
496
511
// using time_t causes problems on 32-bit systems and windows x64.
497
512
int64_t PortableTimeGM (struct tm * t) {
@@ -512,6 +527,7 @@ int64_t PortableTimeGM(struct tm* t) {
512
527
t->tm_min ) +
513
528
t->tm_sec ;
514
529
}
530
+ #endif
515
531
516
532
// ============================================================================
517
533
// SPKAC
@@ -822,7 +838,7 @@ bool SafeX509SubjectAltNamePrint(const BIOPointer& out, X509_EXTENSION* ext) {
822
838
823
839
bool ok = true ;
824
840
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++) {
826
842
GENERAL_NAME* gen = sk_GENERAL_NAME_value (names, i);
827
843
828
844
if (i != 0 ) BIO_write (out.get (), " , " , 2 );
@@ -846,7 +862,7 @@ bool SafeX509InfoAccessPrint(const BIOPointer& out, X509_EXTENSION* ext) {
846
862
847
863
bool ok = true ;
848
864
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++) {
850
866
ACCESS_DESCRIPTION* desc = sk_ACCESS_DESCRIPTION_value (descs, i);
851
867
852
868
if (i != 0 ) BIO_write (out.get (), " \n " , 1 );
@@ -999,15 +1015,31 @@ BIOPointer X509View::getValidTo() const {
999
1015
}
1000
1016
1001
1017
int64_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
1002
1027
struct tm tp;
1003
1028
ASN1_TIME_to_tm (X509_get0_notAfter (cert_), &tp);
1004
1029
return PortableTimeGM (&tp);
1030
+ #endif
1005
1031
}
1006
1032
1007
1033
int64_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
1008
1039
struct tm tp;
1009
1040
ASN1_TIME_to_tm (X509_get0_notBefore (cert_), &tp);
1010
1041
return PortableTimeGM (&tp);
1042
+ #endif
1011
1043
}
1012
1044
1013
1045
DataPointer X509View::getSerialNumber () const {
@@ -1324,7 +1356,12 @@ BIOPointer BIOPointer::NewMem() {
1324
1356
}
1325
1357
1326
1358
BIOPointer 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
1327
1363
return BIOPointer (BIO_new (BIO_s_secmem ()));
1364
+ #endif
1328
1365
}
1329
1366
1330
1367
BIOPointer BIOPointer::New (const BIO_METHOD* method) {
@@ -1394,8 +1431,11 @@ BignumPointer DHPointer::FindGroup(const std::string_view name,
1394
1431
#define V (n, p ) \
1395
1432
if (EqualNoCase (name, n)) return BignumPointer (p (nullptr ));
1396
1433
if (option != FindGroupOption::NO_SMALL_PRIMES) {
1434
+ #ifndef OPENSSL_IS_BORINGSSL
1435
+ // Boringssl does not support the 768 and 1024 small primes
1397
1436
V (" modp1" , BN_get_rfc2409_prime_768);
1398
1437
V (" modp2" , BN_get_rfc2409_prime_1024);
1438
+ #endif
1399
1439
V (" modp5" , BN_get_rfc3526_prime_1536);
1400
1440
}
1401
1441
V (" modp14" , BN_get_rfc3526_prime_2048);
@@ -1467,15 +1507,22 @@ DHPointer::CheckResult DHPointer::check() {
1467
1507
DHPointer::CheckPublicKeyResult DHPointer::checkPublicKey (
1468
1508
const BignumPointer& pub_key) {
1469
1509
ClearErrorOnReturn clearErrorOnReturn;
1470
- if (!pub_key || !dh_) return DHPointer::CheckPublicKeyResult::CHECK_FAILED;
1510
+ if (!pub_key || !dh_) {
1511
+ return DHPointer::CheckPublicKeyResult::CHECK_FAILED;
1512
+ }
1471
1513
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 ) {
1473
1515
return DHPointer::CheckPublicKeyResult::CHECK_FAILED;
1516
+ }
1517
+ #ifndef OPENSSL_IS_BORINGSSL
1518
+ // Boringssl does not define DH_CHECK_PUBKEY_TOO_SMALL or TOO_LARGE
1474
1519
if (codes & DH_CHECK_PUBKEY_TOO_SMALL) {
1475
1520
return DHPointer::CheckPublicKeyResult::TOO_SMALL;
1476
- } else if (codes & DH_CHECK_PUBKEY_TOO_SMALL ) {
1521
+ } else if (codes & DH_CHECK_PUBKEY_TOO_LARGE ) {
1477
1522
return DHPointer::CheckPublicKeyResult::TOO_LARGE;
1478
- } else if (codes != 0 ) {
1523
+ }
1524
+ #endif
1525
+ if (codes != 0 ) {
1479
1526
return DHPointer::CheckPublicKeyResult::INVALID;
1480
1527
}
1481
1528
return CheckPublicKeyResult::NONE;
@@ -2530,6 +2577,7 @@ std::optional<uint32_t> SSLPointer::verifyPeerCertificate() const {
2530
2577
2531
2578
const std::string_view SSLPointer::getClientHelloAlpn () const {
2532
2579
if (ssl_ == nullptr ) return {};
2580
+ #ifndef OPENSSL_IS_BORINGSSL
2533
2581
const unsigned char * buf;
2534
2582
size_t len;
2535
2583
size_t rem;
@@ -2546,10 +2594,15 @@ const std::string_view SSLPointer::getClientHelloAlpn() const {
2546
2594
len = (buf[0 ] << 8 ) | buf[1 ];
2547
2595
if (len + 2 != rem) return {};
2548
2596
return reinterpret_cast <const char *>(buf + 3 );
2597
+ #else
2598
+ // Boringssl doesn't have a public API for this.
2599
+ return {};
2600
+ #endif
2549
2601
}
2550
2602
2551
2603
const std::string_view SSLPointer::getClientHelloServerName () const {
2552
2604
if (ssl_ == nullptr ) return {};
2605
+ #ifndef OPENSSL_IS_BORINGSSL
2553
2606
const unsigned char * buf;
2554
2607
size_t len;
2555
2608
size_t rem;
@@ -2569,6 +2622,10 @@ const std::string_view SSLPointer::getClientHelloServerName() const {
2569
2622
len = (*(buf + 3 ) << 8 ) | *(buf + 4 );
2570
2623
if (len + 2 > rem) return {};
2571
2624
return reinterpret_cast <const char *>(buf + 5 );
2625
+ #else
2626
+ // Boringssl doesn't have a public API for this.
2627
+ return {};
2628
+ #endif
2572
2629
}
2573
2630
2574
2631
std::optional<const std::string_view> SSLPointer::GetServerName (
@@ -2602,7 +2659,11 @@ bool SSLPointer::isServer() const {
2602
2659
EVPKeyPointer SSLPointer::getPeerTempKey () const {
2603
2660
if (!ssl_) return {};
2604
2661
EVP_PKEY* raw_key = nullptr ;
2662
+ #ifndef OPENSSL_IS_BORINGSSL
2605
2663
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
2606
2667
return EVPKeyPointer (raw_key);
2607
2668
}
2608
2669
@@ -3167,9 +3228,15 @@ int EVPKeyCtxPointer::initForSign() {
3167
3228
}
3168
3229
3169
3230
bool EVPKeyCtxPointer::setDhParameters (int prime_size, uint32_t generator) {
3231
+ #ifndef OPENSSL_IS_BORINGSSL
3170
3232
if (!ctx_) return false ;
3171
3233
return EVP_PKEY_CTX_set_dh_paramgen_prime_len (ctx_.get (), prime_size) == 1 &&
3172
3234
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
3173
3240
}
3174
3241
3175
3242
bool EVPKeyCtxPointer::setDsaParameters (uint32_t bits,
@@ -3249,6 +3316,7 @@ bool EVPKeyCtxPointer::setRsaPssSaltlen(int salt_len) {
3249
3316
}
3250
3317
3251
3318
bool EVPKeyCtxPointer::setRsaImplicitRejection () {
3319
+ #ifndef OPENSSL_IS_BORINGSSL
3252
3320
if (!ctx_) return false ;
3253
3321
return EVP_PKEY_CTX_ctrl_str (
3254
3322
ctx_.get (), " rsa_pkcs1_implicit_rejection" , " 1" ) > 0 ;
@@ -3259,6 +3327,11 @@ bool EVPKeyCtxPointer::setRsaImplicitRejection() {
3259
3327
// of how it is set. The call to set the value
3260
3328
// will not affect what is used since a different context is
3261
3329
// 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
3262
3335
}
3263
3336
3264
3337
bool EVPKeyCtxPointer::setRsaOaepLabel (DataPointer&& data) {
@@ -3311,16 +3384,31 @@ EVPKeyPointer EVPKeyCtxPointer::paramgen() const {
3311
3384
3312
3385
bool EVPKeyCtxPointer::publicCheck () const {
3313
3386
if (!ctx_) return false ;
3387
+ #ifndef OPENSSL_IS_BORINGSSL
3388
+ return EVP_PKEY_public_check (ctx_.get ()) == 1 ;
3314
3389
#if OPENSSL_VERSION_MAJOR >= 3
3315
3390
return EVP_PKEY_public_check_quick (ctx_.get ()) == 1 ;
3316
3391
#else
3317
3392
return EVP_PKEY_public_check (ctx_.get ()) == 1 ;
3318
3393
#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
3319
3400
}
3320
3401
3321
3402
bool EVPKeyCtxPointer::privateCheck () const {
3322
3403
if (!ctx_) return false ;
3404
+ #ifndef OPENSSL_IS_BORINGSSL
3323
3405
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
3324
3412
}
3325
3413
3326
3414
bool EVPKeyCtxPointer::verify (const Buffer<const unsigned char >& sig,
0 commit comments