proxygen
OpenSSL.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2016-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
18 
19 #include <stdexcept>
20 
21 namespace folly {
22 namespace portability {
23 namespace ssl {
24 
25 #ifdef OPENSSL_IS_BORINGSSL
26 int SSL_CTX_set1_sigalgs_list(SSL_CTX*, const char*) {
27  return 1; // 0 implies error
28 }
29 
30 int TLS1_get_client_version(SSL* s) {
31  // Note that this isn't the client version, and the API to
32  // get this has been hidden. It may be found by parsing the
33  // ClientHello (there is a callback via the SSL_HANDSHAKE struct)
34  return s->version;
35 }
36 #endif
37 
38 #if FOLLY_OPENSSL_IS_100
39 uint32_t SSL_CIPHER_get_id(const SSL_CIPHER* c) {
40  return c->id;
41 }
42 
43 int TLS1_get_client_version(const SSL* s) {
44  return (s->client_version >> 8) == TLS1_VERSION_MAJOR ? s->client_version : 0;
45 }
46 #endif
47 
48 #if FOLLY_OPENSSL_IS_100 || FOLLY_OPENSSL_IS_101
49 int X509_get_signature_nid(X509* cert) {
50  return OBJ_obj2nid(cert->sig_alg->algorithm);
51 }
52 #endif
53 
54 #if FOLLY_OPENSSL_IS_100 || FOLLY_OPENSSL_IS_101 || FOLLY_OPENSSL_IS_102
55 int SSL_CTX_up_ref(SSL_CTX* ctx) {
56  return CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX);
57 }
58 
59 int SSL_SESSION_up_ref(SSL_SESSION* session) {
60  return CRYPTO_add(&session->references, 1, CRYPTO_LOCK_SSL_SESSION);
61 }
62 
63 int X509_up_ref(X509* x) {
64  return CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
65 }
66 
67 int X509_STORE_up_ref(X509_STORE* v) {
68  return CRYPTO_add(&v->references, 1, CRYPTO_LOCK_X509_STORE);
69 }
70 
71 int EVP_PKEY_up_ref(EVP_PKEY* evp) {
72  return CRYPTO_add(&evp->references, 1, CRYPTO_LOCK_EVP_PKEY);
73 }
74 
75 void RSA_get0_key(
76  const RSA* r,
77  const BIGNUM** n,
78  const BIGNUM** e,
79  const BIGNUM** d) {
80  if (n != nullptr) {
81  *n = r->n;
82  }
83  if (e != nullptr) {
84  *e = r->e;
85  }
86  if (d != nullptr) {
87  *d = r->d;
88  }
89 }
90 
91 RSA* EVP_PKEY_get0_RSA(EVP_PKEY* pkey) {
92  if (pkey->type != EVP_PKEY_RSA) {
93  return nullptr;
94  }
95  return pkey->pkey.rsa;
96 }
97 
98 DSA* EVP_PKEY_get0_DSA(EVP_PKEY* pkey) {
99  if (pkey->type != EVP_PKEY_DSA) {
100  return nullptr;
101  }
102  return pkey->pkey.dsa;
103 }
104 
105 DH* EVP_PKEY_get0_DH(EVP_PKEY* pkey) {
106  if (pkey->type != EVP_PKEY_DH) {
107  return nullptr;
108  }
109  return pkey->pkey.dh;
110 }
111 
112 EC_KEY* EVP_PKEY_get0_EC_KEY(EVP_PKEY* pkey) {
113  if (pkey->type != EVP_PKEY_EC) {
114  return nullptr;
115  }
116  return pkey->pkey.ec;
117 }
118 #endif
119 
120 #if !FOLLY_OPENSSL_IS_110
121 BIO_METHOD* BIO_meth_new(int type, const char* name) {
122  BIO_METHOD* method = (BIO_METHOD*)OPENSSL_malloc(sizeof(BIO_METHOD));
123  if (method == nullptr) {
124  return nullptr;
125  }
126  memset(method, 0, sizeof(BIO_METHOD));
127  method->type = type;
128  method->name = name;
129  return method;
130 }
131 
132 void BIO_meth_free(BIO_METHOD* biom) {
133  OPENSSL_free((void*)biom);
134 }
135 
136 int BIO_meth_set_read(BIO_METHOD* biom, int (*read)(BIO*, char*, int)) {
137  biom->bread = read;
138  return 1;
139 }
140 
141 int BIO_meth_set_write(BIO_METHOD* biom, int (*write)(BIO*, const char*, int)) {
142  biom->bwrite = write;
143  return 1;
144 }
145 
146 int BIO_meth_set_puts(BIO_METHOD* biom, int (*bputs)(BIO*, const char*)) {
147  biom->bputs = bputs;
148  return 1;
149 }
150 
151 int BIO_meth_set_gets(BIO_METHOD* biom, int (*bgets)(BIO*, char*, int)) {
152  biom->bgets = bgets;
153  return 1;
154 }
155 
156 int BIO_meth_set_ctrl(BIO_METHOD* biom, long (*ctrl)(BIO*, int, long, void*)) {
157  biom->ctrl = ctrl;
158  return 1;
159 }
160 
161 int BIO_meth_set_create(BIO_METHOD* biom, int (*create)(BIO*)) {
162  biom->create = create;
163  return 1;
164 }
165 
166 int BIO_meth_set_destroy(BIO_METHOD* biom, int (*destroy)(BIO*)) {
167  biom->destroy = destroy;
168  return 1;
169 }
170 
171 void BIO_set_data(BIO* bio, void* ptr) {
172  bio->ptr = ptr;
173 }
174 
175 void* BIO_get_data(BIO* bio) {
176  return bio->ptr;
177 }
178 
179 void BIO_set_init(BIO* bio, int init) {
180  bio->init = init;
181 }
182 
183 void BIO_set_shutdown(BIO* bio, int shutdown) {
184  bio->shutdown = shutdown;
185 }
186 
187 const SSL_METHOD* TLS_server_method(void) {
188  return TLSv1_2_server_method();
189 }
190 
191 const SSL_METHOD* TLS_client_method(void) {
192  return TLSv1_2_client_method();
193 }
194 
195 const char* SSL_SESSION_get0_hostname(const SSL_SESSION* s) {
196  return s->tlsext_hostname;
197 }
198 
199 unsigned char* ASN1_STRING_get0_data(const ASN1_STRING* x) {
200  return ASN1_STRING_data((ASN1_STRING*)x);
201 }
202 
203 int SSL_SESSION_has_ticket(const SSL_SESSION* s) {
204  return (s->tlsext_ticklen > 0) ? 1 : 0;
205 }
206 
207 unsigned long SSL_SESSION_get_ticket_lifetime_hint(const SSL_SESSION* s) {
208  return s->tlsext_tick_lifetime_hint;
209 }
210 
211 // This is taken from OpenSSL 1.1.0
212 int DH_set0_pqg(DH* dh, BIGNUM* p, BIGNUM* q, BIGNUM* g) {
213  /* If the fields p and g in d are nullptr, the corresponding input
214  * parameters MUST not be nullptr. q may remain nullptr.
215  */
216  if (dh == nullptr || (dh->p == nullptr && p == nullptr) ||
217  (dh->g == nullptr && g == nullptr)) {
218  return 0;
219  }
220 
221  if (p != nullptr) {
222  BN_free(dh->p);
223  dh->p = p;
224  }
225  if (q != nullptr) {
226  BN_free(dh->q);
227  dh->q = q;
228  }
229  if (g != nullptr) {
230  BN_free(dh->g);
231  dh->g = g;
232  }
233 
234  // In OpenSSL 1.1.0, DH_set0_pqg also sets
235  // dh->length = BN_num_bits(q)
236  // With OpenSSL 1.0.2, the output of openssl dhparam -C 2048 doesn't set
237  // the length field. So as far as the compat lib is concerned, this wrapper
238  // mimics the functionality of OpenSSL 1.0.2
239  // Note: BoringSSL doesn't even have a length field anymore, just something
240  // called 'priv_length'. Let's not mess with that for now.
241 
242  return 1;
243 }
244 
246  const DH* dh,
247  const BIGNUM** p,
248  const BIGNUM** q,
249  const BIGNUM** g) {
250  // Based off of https://wiki.openssl.org/index.php/OpenSSL_1.1.0_Changes
251  if (p != nullptr) {
252  *p = dh->p;
253  }
254  if (q != nullptr) {
255  *q = dh->q;
256  }
257  if (g != nullptr) {
258  *g = dh->g;
259  }
260 }
261 
263  const DH* dh,
264  const BIGNUM** pub_key,
265  const BIGNUM** priv_key) {
266  // Based off of https://wiki.openssl.org/index.php/OpenSSL_1.1.0_Changes
267  if (pub_key != nullptr) {
268  *pub_key = dh->pub_key;
269  }
270  if (priv_key != nullptr) {
271  *priv_key = dh->priv_key;
272  }
273 }
274 
276  const DSA* dsa,
277  const BIGNUM** p,
278  const BIGNUM** q,
279  const BIGNUM** g) {
280  // Based off of https://wiki.openssl.org/index.php/OpenSSL_1.1.0_Changes
281  if (p != nullptr) {
282  *p = dsa->p;
283  }
284  if (q != nullptr) {
285  *q = dsa->q;
286  }
287  if (g != nullptr) {
288  *g = dsa->g;
289  }
290 }
291 
293  const DSA* dsa,
294  const BIGNUM** pub_key,
295  const BIGNUM** priv_key) {
296  // Based off of https://wiki.openssl.org/index.php/OpenSSL_1.1.0_Changes
297  if (pub_key != nullptr) {
298  *pub_key = dsa->pub_key;
299  }
300  if (priv_key != nullptr) {
301  *priv_key = dsa->priv_key;
302  }
303 }
304 
305 STACK_OF(X509_OBJECT) * X509_STORE_get0_objects(X509_STORE* store) {
306  return store->objs;
307 }
308 
309 X509* X509_STORE_CTX_get0_cert(X509_STORE_CTX* ctx) {
310  return ctx->cert;
311 }
312 
313 STACK_OF(X509) * X509_STORE_CTX_get0_chain(X509_STORE_CTX* ctx) {
314  return X509_STORE_CTX_get_chain(ctx);
315 }
316 
317 STACK_OF(X509) * X509_STORE_CTX_get0_untrusted(X509_STORE_CTX* ctx) {
318  return ctx->untrusted;
319 }
320 
321 EVP_MD_CTX* EVP_MD_CTX_new() {
322  EVP_MD_CTX* ctx = (EVP_MD_CTX*)OPENSSL_malloc(sizeof(EVP_MD_CTX));
323  if (!ctx) {
324  throw std::runtime_error("Cannot allocate EVP_MD_CTX");
325  }
326  EVP_MD_CTX_init(ctx);
327  return ctx;
328 }
329 
330 void EVP_MD_CTX_free(EVP_MD_CTX* ctx) {
331  if (ctx) {
332  EVP_MD_CTX_cleanup(ctx);
333  OPENSSL_free(ctx);
334  }
335 }
336 
337 HMAC_CTX* HMAC_CTX_new() {
338  HMAC_CTX* ctx = (HMAC_CTX*)OPENSSL_malloc(sizeof(HMAC_CTX));
339  if (!ctx) {
340  throw std::runtime_error("Cannot allocate HMAC_CTX");
341  }
342  HMAC_CTX_init(ctx);
343  return ctx;
344 }
345 
346 void HMAC_CTX_free(HMAC_CTX* ctx) {
347  if (ctx) {
348  HMAC_CTX_cleanup(ctx);
349  OPENSSL_free(ctx);
350  }
351 }
352 
353 bool RSA_set0_key(RSA* r, BIGNUM* n, BIGNUM* e, BIGNUM* d) {
354  // Based off of https://wiki.openssl.org/index.php/OpenSSL_1.1.0_Changes
360  if ((r->n == nullptr && n == nullptr) || (r->e == nullptr && e == nullptr)) {
361  return false;
362  }
363  if (n != nullptr) {
364  BN_free(r->n);
365  r->n = n;
366  }
367  if (e != nullptr) {
368  BN_free(r->e);
369  r->e = e;
370  }
371  if (d != nullptr) {
372  BN_free(r->d);
373  r->d = d;
374  }
375  return true;
376 }
377 
378 void RSA_get0_factors(const RSA* r, const BIGNUM** p, const BIGNUM** q) {
379  // Based off of https://wiki.openssl.org/index.php/OpenSSL_1.1.0_Changes
380  if (p != nullptr) {
381  *p = r->p;
382  }
383  if (q != nullptr) {
384  *q = r->q;
385  }
386 }
387 
389  const RSA* r,
390  const BIGNUM** dmp1,
391  const BIGNUM** dmq1,
392  const BIGNUM** iqmp) {
393  // Based off of https://wiki.openssl.org/index.php/OpenSSL_1.1.0_Changes
394  if (dmp1 != nullptr) {
395  *dmp1 = r->dmp1;
396  }
397  if (dmq1 != nullptr) {
398  *dmq1 = r->dmq1;
399  }
400  if (iqmp != nullptr) {
401  *iqmp = r->iqmp;
402  }
403 }
404 
405 int ECDSA_SIG_set0(ECDSA_SIG* sig, BIGNUM* r, BIGNUM* s) {
406  // Based off of https://wiki.openssl.org/index.php/OpenSSL_1.1.0_Changes
407  if (r == nullptr || s == nullptr) {
408  return 0;
409  }
410  BN_clear_free(sig->r);
411  BN_clear_free(sig->s);
412  sig->r = r;
413  sig->s = s;
414  return 1;
415 }
416 
418  const ECDSA_SIG* sig,
419  const BIGNUM** pr,
420  const BIGNUM** ps) {
421  // Based off of https://wiki.openssl.org/index.php/OpenSSL_1.1.0_Changes
422  if (pr != nullptr) {
423  *pr = sig->r;
424  }
425  if (ps != nullptr) {
426  *ps = sig->s;
427  }
428 }
429 
437  // OpenSSL >= 1.1.0 handles initializing the library, adding digests &
438  // ciphers, loading strings. Additionally, OpenSSL >= 1.1.0 uses platform
439  // native threading & mutexes, which means that we should handle setting up
440  // the necessary threading initialization in the compat layer as well.
441  SSL_library_init();
442  OpenSSL_add_all_ciphers();
443  OpenSSL_add_all_digests();
444  OpenSSL_add_all_algorithms();
445 
446  SSL_load_error_strings();
447  ERR_load_crypto_strings();
448 
449  // The caller should have used SSLContext::setLockTypes() prior to calling
450  // this function.
452  return 0;
453 }
454 
457  CRYPTO_cleanup_all_ex_data();
458  ERR_free_strings();
459  EVP_cleanup();
460  ERR_clear_error();
461 }
462 
463 const ASN1_INTEGER* X509_REVOKED_get0_serialNumber(const X509_REVOKED* r) {
464  return r->serialNumber;
465 }
466 
467 const ASN1_TIME* X509_REVOKED_get0_revocationDate(const X509_REVOKED* r) {
468  return r->revocationDate;
469 }
470 
472  return x->ex_flags;
473 }
474 
476  return x->ex_kusage;
477 }
478 
480  return x->ex_xkusage;
481 }
482 
483 int X509_OBJECT_get_type(const X509_OBJECT* obj) {
484  return obj->type;
485 }
486 
487 X509* X509_OBJECT_get0_X509(const X509_OBJECT* obj) {
488  if (obj == nullptr || obj->type != X509_LU_X509) {
489  return nullptr;
490  }
491  return obj->data.x509;
492 }
493 
494 const ASN1_TIME* X509_CRL_get0_lastUpdate(const X509_CRL* crl) {
495  return X509_CRL_get_lastUpdate(crl);
496 }
497 
498 const ASN1_TIME* X509_CRL_get0_nextUpdate(const X509_CRL* crl) {
499  return X509_CRL_get_nextUpdate(crl);
500 }
501 
502 const X509_ALGOR* X509_get0_tbs_sigalg(const X509* x) {
503  return x->cert_info->signature;
504 }
505 
506 #endif // !FOLLY_OPENSSL_IS_110
507 } // namespace ssl
508 } // namespace portability
509 } // namespace folly
Definition: InvokeTest.cpp:58
void * ptr
X509 * X509_OBJECT_get0_X509(const X509_OBJECT *obj)
Definition: OpenSSL.cpp:487
const X509_ALGOR * X509_get0_tbs_sigalg(const X509 *x)
Definition: OpenSSL.cpp:502
int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g)
Definition: OpenSSL.cpp:212
void write(const T &in, folly::io::Appender &appender)
Definition: Types-inl.h:112
void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
Definition: OpenSSL.cpp:417
void BIO_set_data(BIO *bio, void *ptr)
Definition: OpenSSL.cpp:171
int BIO_meth_set_destroy(BIO_METHOD *biom, int(*destroy)(BIO *))
Definition: OpenSSL.cpp:166
PskType type
bool RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d)
Definition: OpenSSL.cpp:353
void DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
Definition: OpenSSL.cpp:245
const ASN1_INTEGER * X509_REVOKED_get0_serialNumber(const X509_REVOKED *r)
Definition: OpenSSL.cpp:463
STACK_OF(X509_OBJECT)*X509_STORE_get0_objects(X509_STORE *store)
Definition: OpenSSL.cpp:305
X509 * X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx)
Definition: OpenSSL.cpp:309
int BIO_meth_set_create(BIO_METHOD *biom, int(*create)(BIO *))
Definition: OpenSSL.cpp:161
unsigned char * ASN1_STRING_get0_data(const ASN1_STRING *x)
Definition: OpenSSL.cpp:199
void BIO_meth_free(BIO_METHOD *biom)
Definition: OpenSSL.cpp:132
void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key)
Definition: OpenSSL.cpp:262
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
int OPENSSL_init_ssl(uint64_t, const OPENSSL_INIT_SETTINGS *)
Definition: OpenSSL.cpp:436
const SSL_METHOD * TLS_client_method(void)
Definition: OpenSSL.cpp:191
int BIO_meth_set_write(BIO_METHOD *biom, int(*write)(BIO *, const char *, int))
Definition: OpenSSL.cpp:141
void * BIO_get_data(BIO *bio)
Definition: OpenSSL.cpp:175
static void destroy()
void init(int *argc, char ***argv, bool removeFlags)
Definition: Init.cpp:34
uint32_t X509_get_extended_key_usage(X509 *x)
Definition: OpenSSL.cpp:479
int BIO_meth_set_gets(BIO_METHOD *biom, int(*bgets)(BIO *, char *, int))
Definition: OpenSSL.cpp:151
const char * name
Definition: http_parser.c:437
HMAC_CTX * HMAC_CTX_new()
Definition: OpenSSL.cpp:337
int SSL_SESSION_has_ticket(const SSL_SESSION *s)
Definition: OpenSSL.cpp:203
int BIO_meth_set_ctrl(BIO_METHOD *biom, long(*ctrl)(BIO *, int, long, void *))
Definition: OpenSSL.cpp:156
uint32_t X509_get_extension_flags(X509 *x)
Definition: OpenSSL.cpp:471
size_t read(T &out, folly::io::Cursor &cursor)
Definition: Types-inl.h:258
int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s)
Definition: OpenSSL.cpp:405
const ASN1_TIME * X509_CRL_get0_nextUpdate(const X509_CRL *crl)
Definition: OpenSSL.cpp:498
const ASN1_TIME * X509_REVOKED_get0_revocationDate(const X509_REVOKED *r)
Definition: OpenSSL.cpp:467
void RSA_get0_crt_params(const RSA *r, const BIGNUM **dmp1, const BIGNUM **dmq1, const BIGNUM **iqmp)
Definition: OpenSSL.cpp:388
const ASN1_TIME * X509_CRL_get0_lastUpdate(const X509_CRL *crl)
Definition: OpenSSL.cpp:494
uint32_t X509_get_key_usage(X509 *x)
Definition: OpenSSL.cpp:475
void DSA_get0_pqg(const DSA *dsa, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
Definition: OpenSSL.cpp:275
constexpr detail::Sig< Sig > const sig
Definition: Poly.h:1165
void shutdown(Counter &)
void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q)
Definition: OpenSSL.cpp:378
const char * SSL_SESSION_get0_hostname(const SSL_SESSION *s)
Definition: OpenSSL.cpp:195
void BIO_set_init(BIO *bio, int init)
Definition: OpenSSL.cpp:179
const SSL_METHOD * TLS_server_method(void)
Definition: OpenSSL.cpp:187
void BIO_set_shutdown(BIO *bio, int shutdown)
Definition: OpenSSL.cpp:183
unsigned long SSL_SESSION_get_ticket_lifetime_hint(const SSL_SESSION *s)
Definition: OpenSSL.cpp:207
int X509_OBJECT_get_type(const X509_OBJECT *obj)
Definition: OpenSSL.cpp:483
void EVP_MD_CTX_free(EVP_MD_CTX *ctx)
Definition: OpenSSL.cpp:330
void DSA_get0_key(const DSA *dsa, const BIGNUM **pub_key, const BIGNUM **priv_key)
Definition: OpenSSL.cpp:292
g_t g(f_t)
EVP_MD_CTX * EVP_MD_CTX_new()
Definition: OpenSSL.cpp:321
static set< string > s
void HMAC_CTX_free(HMAC_CTX *ctx)
Definition: OpenSSL.cpp:346
BIO_METHOD * BIO_meth_new(int type, const char *name)
Definition: OpenSSL.cpp:121
char c
int BIO_meth_set_puts(BIO_METHOD *biom, int(*bputs)(BIO *, const char *))
Definition: OpenSSL.cpp:146
int BIO_meth_set_read(BIO_METHOD *biom, int(*read)(BIO *, char *, int))
Definition: OpenSSL.cpp:136