• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2  * All rights reserved.
3  *
4  * This package is an SSL implementation written
5  * by Eric Young (eay@cryptsoft.com).
6  * The implementation was written so as to conform with Netscapes SSL.
7  *
8  * This library is free for commercial and non-commercial use as long as
9  * the following conditions are aheared to.  The following conditions
10  * apply to all code found in this distribution, be it the RC4, RSA,
11  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
12  * included with this distribution is covered by the same copyright terms
13  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14  *
15  * Copyright remains Eric Young's, and as such any Copyright notices in
16  * the code are not to be removed.
17  * If this package is used in a product, Eric Young should be given attribution
18  * as the author of the parts of the library used.
19  * This can be in the form of a textual message at program startup or
20  * in documentation (online or textual) provided with the package.
21  *
22  * Redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions
24  * are met:
25  * 1. Redistributions of source code must retain the copyright
26  *    notice, this list of conditions and the following disclaimer.
27  * 2. Redistributions in binary form must reproduce the above copyright
28  *    notice, this list of conditions and the following disclaimer in the
29  *    documentation and/or other materials provided with the distribution.
30  * 3. All advertising materials mentioning features or use of this software
31  *    must display the following acknowledgement:
32  *    "This product includes cryptographic software written by
33  *     Eric Young (eay@cryptsoft.com)"
34  *    The word 'cryptographic' can be left out if the rouines from the library
35  *    being used are not cryptographic related :-).
36  * 4. If you include any Windows specific code (or a derivative thereof) from
37  *    the apps directory (application code) you must include an acknowledgement:
38  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39  *
40  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50  * SUCH DAMAGE.
51  *
52  * The licence and distribution terms for any publically available version or
53  * derivative of this code cannot be changed.  i.e. this code cannot simply be
54  * copied and put under another distribution licence
55  * [including the GNU Public Licence.] */
56 
57 #include <openssl/ssl.h>
58 
59 #include <assert.h>
60 #include <limits.h>
61 
62 #include <openssl/ec.h>
63 #include <openssl/ec_key.h>
64 #include <openssl/err.h>
65 #include <openssl/evp.h>
66 #include <openssl/mem.h>
67 
68 #include "internal.h"
69 #include "../crypto/internal.h"
70 
71 
72 namespace bssl {
73 
ssl_is_key_type_supported(int key_type)74 int ssl_is_key_type_supported(int key_type) {
75   return key_type == EVP_PKEY_RSA || key_type == EVP_PKEY_EC ||
76          key_type == EVP_PKEY_ED25519;
77 }
78 
ssl_set_pkey(CERT * cert,EVP_PKEY * pkey)79 static int ssl_set_pkey(CERT *cert, EVP_PKEY *pkey) {
80   if (!ssl_is_key_type_supported(pkey->type)) {
81     OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
82     return 0;
83   }
84 
85   if (cert->chain != NULL &&
86       sk_CRYPTO_BUFFER_value(cert->chain, 0) != NULL &&
87       // Sanity-check that the private key and the certificate match.
88       !ssl_cert_check_private_key(cert, pkey)) {
89     return 0;
90   }
91 
92   EVP_PKEY_free(cert->privatekey);
93   EVP_PKEY_up_ref(pkey);
94   cert->privatekey = pkey;
95 
96   return 1;
97 }
98 
99 typedef struct {
100   uint16_t sigalg;
101   int pkey_type;
102   int curve;
103   const EVP_MD *(*digest_func)(void);
104   char is_rsa_pss;
105 } SSL_SIGNATURE_ALGORITHM;
106 
107 static const SSL_SIGNATURE_ALGORITHM kSignatureAlgorithms[] = {
108     {SSL_SIGN_RSA_PKCS1_MD5_SHA1, EVP_PKEY_RSA, NID_undef, &EVP_md5_sha1, 0},
109     {SSL_SIGN_RSA_PKCS1_SHA1, EVP_PKEY_RSA, NID_undef, &EVP_sha1, 0},
110     {SSL_SIGN_RSA_PKCS1_SHA256, EVP_PKEY_RSA, NID_undef, &EVP_sha256, 0},
111     {SSL_SIGN_RSA_PKCS1_SHA384, EVP_PKEY_RSA, NID_undef, &EVP_sha384, 0},
112     {SSL_SIGN_RSA_PKCS1_SHA512, EVP_PKEY_RSA, NID_undef, &EVP_sha512, 0},
113 
114     {SSL_SIGN_RSA_PSS_SHA256, EVP_PKEY_RSA, NID_undef, &EVP_sha256, 1},
115     {SSL_SIGN_RSA_PSS_SHA384, EVP_PKEY_RSA, NID_undef, &EVP_sha384, 1},
116     {SSL_SIGN_RSA_PSS_SHA512, EVP_PKEY_RSA, NID_undef, &EVP_sha512, 1},
117 
118     {SSL_SIGN_ECDSA_SHA1, EVP_PKEY_EC, NID_undef, &EVP_sha1, 0},
119     {SSL_SIGN_ECDSA_SECP256R1_SHA256, EVP_PKEY_EC, NID_X9_62_prime256v1,
120      &EVP_sha256, 0},
121     {SSL_SIGN_ECDSA_SECP384R1_SHA384, EVP_PKEY_EC, NID_secp384r1, &EVP_sha384,
122      0},
123     {SSL_SIGN_ECDSA_SECP521R1_SHA512, EVP_PKEY_EC, NID_secp521r1, &EVP_sha512,
124      0},
125 
126     {SSL_SIGN_ED25519, EVP_PKEY_ED25519, NID_undef, NULL, 0},
127 };
128 
get_signature_algorithm(uint16_t sigalg)129 static const SSL_SIGNATURE_ALGORITHM *get_signature_algorithm(uint16_t sigalg) {
130   for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kSignatureAlgorithms); i++) {
131     if (kSignatureAlgorithms[i].sigalg == sigalg) {
132       return &kSignatureAlgorithms[i];
133     }
134   }
135   return NULL;
136 }
137 
ssl_has_private_key(const SSL * ssl)138 int ssl_has_private_key(const SSL *ssl) {
139   return ssl->cert->privatekey != NULL || ssl->cert->key_method != NULL;
140 }
141 
pkey_supports_algorithm(const SSL * ssl,EVP_PKEY * pkey,uint16_t sigalg)142 static int pkey_supports_algorithm(const SSL *ssl, EVP_PKEY *pkey,
143                                    uint16_t sigalg) {
144   const SSL_SIGNATURE_ALGORITHM *alg = get_signature_algorithm(sigalg);
145   if (alg == NULL ||
146       EVP_PKEY_id(pkey) != alg->pkey_type) {
147     return 0;
148   }
149 
150   if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
151     // RSA keys may only be used with RSA-PSS.
152     if (alg->pkey_type == EVP_PKEY_RSA && !alg->is_rsa_pss) {
153       return 0;
154     }
155 
156     // EC keys have a curve requirement.
157     if (alg->pkey_type == EVP_PKEY_EC &&
158         (alg->curve == NID_undef ||
159          EC_GROUP_get_curve_name(
160              EC_KEY_get0_group(EVP_PKEY_get0_EC_KEY(pkey))) != alg->curve)) {
161       return 0;
162     }
163   }
164 
165   return 1;
166 }
167 
setup_ctx(SSL * ssl,EVP_MD_CTX * ctx,EVP_PKEY * pkey,uint16_t sigalg,int is_verify)168 static int setup_ctx(SSL *ssl, EVP_MD_CTX *ctx, EVP_PKEY *pkey, uint16_t sigalg,
169                      int is_verify) {
170   if (!pkey_supports_algorithm(ssl, pkey, sigalg)) {
171     OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE);
172     return 0;
173   }
174 
175   const SSL_SIGNATURE_ALGORITHM *alg = get_signature_algorithm(sigalg);
176   const EVP_MD *digest = alg->digest_func != NULL ? alg->digest_func() : NULL;
177   EVP_PKEY_CTX *pctx;
178   if (is_verify) {
179     if (!EVP_DigestVerifyInit(ctx, &pctx, digest, NULL, pkey)) {
180       return 0;
181     }
182   } else if (!EVP_DigestSignInit(ctx, &pctx, digest, NULL, pkey)) {
183     return 0;
184   }
185 
186   if (alg->is_rsa_pss) {
187     if (!EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) ||
188         !EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1 /* salt len = hash len */)) {
189       return 0;
190     }
191   }
192 
193   return 1;
194 }
195 
ssl_private_key_sign(SSL_HANDSHAKE * hs,uint8_t * out,size_t * out_len,size_t max_out,uint16_t sigalg,Span<const uint8_t> in)196 enum ssl_private_key_result_t ssl_private_key_sign(
197     SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len, size_t max_out,
198     uint16_t sigalg, Span<const uint8_t> in) {
199   SSL *const ssl = hs->ssl;
200   if (ssl->cert->key_method != NULL) {
201     enum ssl_private_key_result_t ret;
202     if (hs->pending_private_key_op) {
203       ret = ssl->cert->key_method->complete(ssl, out, out_len, max_out);
204     } else {
205       ret = ssl->cert->key_method->sign(ssl, out, out_len, max_out, sigalg,
206                                         in.data(), in.size());
207     }
208     if (ret == ssl_private_key_failure) {
209       OPENSSL_PUT_ERROR(SSL, SSL_R_PRIVATE_KEY_OPERATION_FAILED);
210     }
211     hs->pending_private_key_op = ret == ssl_private_key_retry;
212     return ret;
213   }
214 
215   *out_len = max_out;
216   ScopedEVP_MD_CTX ctx;
217   if (!setup_ctx(ssl, ctx.get(), ssl->cert->privatekey, sigalg, 0 /* sign */) ||
218       !EVP_DigestSign(ctx.get(), out, out_len, in.data(), in.size())) {
219     return ssl_private_key_failure;
220   }
221   return ssl_private_key_success;
222 }
223 
ssl_public_key_verify(SSL * ssl,Span<const uint8_t> signature,uint16_t sigalg,EVP_PKEY * pkey,Span<const uint8_t> in)224 bool ssl_public_key_verify(SSL *ssl, Span<const uint8_t> signature,
225                            uint16_t sigalg, EVP_PKEY *pkey,
226                            Span<const uint8_t> in) {
227   ScopedEVP_MD_CTX ctx;
228   return setup_ctx(ssl, ctx.get(), pkey, sigalg, 1 /* verify */) &&
229          EVP_DigestVerify(ctx.get(), signature.data(), signature.size(),
230                           in.data(), in.size());
231 }
232 
ssl_private_key_decrypt(SSL_HANDSHAKE * hs,uint8_t * out,size_t * out_len,size_t max_out,Span<const uint8_t> in)233 enum ssl_private_key_result_t ssl_private_key_decrypt(SSL_HANDSHAKE *hs,
234                                                       uint8_t *out,
235                                                       size_t *out_len,
236                                                       size_t max_out,
237                                                       Span<const uint8_t> in) {
238   SSL *const ssl = hs->ssl;
239   if (ssl->cert->key_method != NULL) {
240     enum ssl_private_key_result_t ret;
241     if (hs->pending_private_key_op) {
242       ret = ssl->cert->key_method->complete(ssl, out, out_len, max_out);
243     } else {
244       ret = ssl->cert->key_method->decrypt(ssl, out, out_len, max_out,
245                                            in.data(), in.size());
246     }
247     if (ret == ssl_private_key_failure) {
248       OPENSSL_PUT_ERROR(SSL, SSL_R_PRIVATE_KEY_OPERATION_FAILED);
249     }
250     hs->pending_private_key_op = ret == ssl_private_key_retry;
251     return ret;
252   }
253 
254   RSA *rsa = EVP_PKEY_get0_RSA(ssl->cert->privatekey);
255   if (rsa == NULL) {
256     // Decrypt operations are only supported for RSA keys.
257     OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
258     return ssl_private_key_failure;
259   }
260 
261   // Decrypt with no padding. PKCS#1 padding will be removed as part of the
262   // timing-sensitive code by the caller.
263   if (!RSA_decrypt(rsa, out_len, out, max_out, in.data(), in.size(),
264                    RSA_NO_PADDING)) {
265     return ssl_private_key_failure;
266   }
267   return ssl_private_key_success;
268 }
269 
ssl_private_key_supports_signature_algorithm(SSL_HANDSHAKE * hs,uint16_t sigalg)270 bool ssl_private_key_supports_signature_algorithm(SSL_HANDSHAKE *hs,
271                                                   uint16_t sigalg) {
272   SSL *const ssl = hs->ssl;
273   if (!pkey_supports_algorithm(ssl, hs->local_pubkey.get(), sigalg)) {
274     return false;
275   }
276 
277   // Ensure the RSA key is large enough for the hash. RSASSA-PSS requires that
278   // emLen be at least hLen + sLen + 2. Both hLen and sLen are the size of the
279   // hash in TLS. Reasonable RSA key sizes are large enough for the largest
280   // defined RSASSA-PSS algorithm, but 1024-bit RSA is slightly too small for
281   // SHA-512. 1024-bit RSA is sometimes used for test credentials, so check the
282   // size so that we can fall back to another algorithm in that case.
283   const SSL_SIGNATURE_ALGORITHM *alg = get_signature_algorithm(sigalg);
284   if (alg->is_rsa_pss && (size_t)EVP_PKEY_size(hs->local_pubkey.get()) <
285                              2 * EVP_MD_size(alg->digest_func()) + 2) {
286     return false;
287   }
288 
289   return true;
290 }
291 
292 }  // namespace bssl
293 
294 using namespace bssl;
295 
SSL_use_RSAPrivateKey(SSL * ssl,RSA * rsa)296 int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa) {
297   if (rsa == NULL) {
298     OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
299     return 0;
300   }
301 
302   UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new());
303   if (!pkey ||
304       !EVP_PKEY_set1_RSA(pkey.get(), rsa)) {
305     OPENSSL_PUT_ERROR(SSL, ERR_R_EVP_LIB);
306     return 0;
307   }
308 
309   return ssl_set_pkey(ssl->cert, pkey.get());
310 }
311 
SSL_use_RSAPrivateKey_ASN1(SSL * ssl,const uint8_t * der,size_t der_len)312 int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const uint8_t *der, size_t der_len) {
313   UniquePtr<RSA> rsa(RSA_private_key_from_bytes(der, der_len));
314   if (!rsa) {
315     OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
316     return 0;
317   }
318 
319   return SSL_use_RSAPrivateKey(ssl, rsa.get());
320 }
321 
SSL_use_PrivateKey(SSL * ssl,EVP_PKEY * pkey)322 int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) {
323   if (pkey == NULL) {
324     OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
325     return 0;
326   }
327 
328   return ssl_set_pkey(ssl->cert, pkey);
329 }
330 
SSL_use_PrivateKey_ASN1(int type,SSL * ssl,const uint8_t * der,size_t der_len)331 int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const uint8_t *der,
332                             size_t der_len) {
333   if (der_len > LONG_MAX) {
334     OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
335     return 0;
336   }
337 
338   const uint8_t *p = der;
339   UniquePtr<EVP_PKEY> pkey(d2i_PrivateKey(type, NULL, &p, (long)der_len));
340   if (!pkey || p != der + der_len) {
341     OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
342     return 0;
343   }
344 
345   return SSL_use_PrivateKey(ssl, pkey.get());
346 }
347 
SSL_CTX_use_RSAPrivateKey(SSL_CTX * ctx,RSA * rsa)348 int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa) {
349   if (rsa == NULL) {
350     OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
351     return 0;
352   }
353 
354   UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new());
355   if (!pkey ||
356       !EVP_PKEY_set1_RSA(pkey.get(), rsa)) {
357     OPENSSL_PUT_ERROR(SSL, ERR_R_EVP_LIB);
358     return 0;
359   }
360 
361   return ssl_set_pkey(ctx->cert, pkey.get());
362 }
363 
SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX * ctx,const uint8_t * der,size_t der_len)364 int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const uint8_t *der,
365                                    size_t der_len) {
366   UniquePtr<RSA> rsa(RSA_private_key_from_bytes(der, der_len));
367   if (!rsa) {
368     OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
369     return 0;
370   }
371 
372   return SSL_CTX_use_RSAPrivateKey(ctx, rsa.get());
373 }
374 
SSL_CTX_use_PrivateKey(SSL_CTX * ctx,EVP_PKEY * pkey)375 int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) {
376   if (pkey == NULL) {
377     OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
378     return 0;
379   }
380 
381   return ssl_set_pkey(ctx->cert, pkey);
382 }
383 
SSL_CTX_use_PrivateKey_ASN1(int type,SSL_CTX * ctx,const uint8_t * der,size_t der_len)384 int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const uint8_t *der,
385                                 size_t der_len) {
386   if (der_len > LONG_MAX) {
387     OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
388     return 0;
389   }
390 
391   const uint8_t *p = der;
392   UniquePtr<EVP_PKEY> pkey(d2i_PrivateKey(type, NULL, &p, (long)der_len));
393   if (!pkey || p != der + der_len) {
394     OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
395     return 0;
396   }
397 
398   return SSL_CTX_use_PrivateKey(ctx, pkey.get());
399 }
400 
SSL_set_private_key_method(SSL * ssl,const SSL_PRIVATE_KEY_METHOD * key_method)401 void SSL_set_private_key_method(SSL *ssl,
402                                 const SSL_PRIVATE_KEY_METHOD *key_method) {
403   ssl->cert->key_method = key_method;
404 }
405 
SSL_CTX_set_private_key_method(SSL_CTX * ctx,const SSL_PRIVATE_KEY_METHOD * key_method)406 void SSL_CTX_set_private_key_method(SSL_CTX *ctx,
407                                     const SSL_PRIVATE_KEY_METHOD *key_method) {
408   ctx->cert->key_method = key_method;
409 }
410 
SSL_get_signature_algorithm_name(uint16_t sigalg,int include_curve)411 const char *SSL_get_signature_algorithm_name(uint16_t sigalg,
412                                              int include_curve) {
413   switch (sigalg) {
414     case SSL_SIGN_RSA_PKCS1_MD5_SHA1:
415       return "rsa_pkcs1_md5_sha1";
416     case SSL_SIGN_RSA_PKCS1_SHA1:
417       return "rsa_pkcs1_sha1";
418     case SSL_SIGN_RSA_PKCS1_SHA256:
419       return "rsa_pkcs1_sha256";
420     case SSL_SIGN_RSA_PKCS1_SHA384:
421       return "rsa_pkcs1_sha384";
422     case SSL_SIGN_RSA_PKCS1_SHA512:
423       return "rsa_pkcs1_sha512";
424     case SSL_SIGN_ECDSA_SHA1:
425       return "ecdsa_sha1";
426     case SSL_SIGN_ECDSA_SECP256R1_SHA256:
427       return include_curve ? "ecdsa_secp256r1_sha256" : "ecdsa_sha256";
428     case SSL_SIGN_ECDSA_SECP384R1_SHA384:
429       return include_curve ? "ecdsa_secp384r1_sha384" : "ecdsa_sha384";
430     case SSL_SIGN_ECDSA_SECP521R1_SHA512:
431       return include_curve ? "ecdsa_secp521r1_sha512" : "ecdsa_sha512";
432     case SSL_SIGN_RSA_PSS_SHA256:
433       return "rsa_pss_sha256";
434     case SSL_SIGN_RSA_PSS_SHA384:
435       return "rsa_pss_sha384";
436     case SSL_SIGN_RSA_PSS_SHA512:
437       return "rsa_pss_sha512";
438     case SSL_SIGN_ED25519:
439       return "ed25519";
440     default:
441       return NULL;
442   }
443 }
444 
SSL_get_signature_algorithm_key_type(uint16_t sigalg)445 int SSL_get_signature_algorithm_key_type(uint16_t sigalg) {
446   const SSL_SIGNATURE_ALGORITHM *alg = get_signature_algorithm(sigalg);
447   return alg != nullptr ? alg->pkey_type : EVP_PKEY_NONE;
448 }
449 
SSL_get_signature_algorithm_digest(uint16_t sigalg)450 const EVP_MD *SSL_get_signature_algorithm_digest(uint16_t sigalg) {
451   const SSL_SIGNATURE_ALGORITHM *alg = get_signature_algorithm(sigalg);
452   if (alg == nullptr || alg->digest_func == nullptr) {
453     return nullptr;
454   }
455   return alg->digest_func();
456 }
457 
SSL_is_signature_algorithm_rsa_pss(uint16_t sigalg)458 int SSL_is_signature_algorithm_rsa_pss(uint16_t sigalg) {
459   const SSL_SIGNATURE_ALGORITHM *alg = get_signature_algorithm(sigalg);
460   return alg != nullptr && alg->is_rsa_pss;
461 }
462 
set_algorithm_prefs(uint16_t ** out_prefs,size_t * out_num_prefs,const uint16_t * prefs,size_t num_prefs)463 static int set_algorithm_prefs(uint16_t **out_prefs, size_t *out_num_prefs,
464                                const uint16_t *prefs, size_t num_prefs) {
465   OPENSSL_free(*out_prefs);
466 
467   *out_num_prefs = 0;
468   *out_prefs = (uint16_t *)BUF_memdup(prefs, num_prefs * sizeof(prefs[0]));
469   if (*out_prefs == NULL) {
470     OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
471     return 0;
472   }
473   *out_num_prefs = num_prefs;
474 
475   return 1;
476 }
477 
SSL_CTX_set_signing_algorithm_prefs(SSL_CTX * ctx,const uint16_t * prefs,size_t num_prefs)478 int SSL_CTX_set_signing_algorithm_prefs(SSL_CTX *ctx, const uint16_t *prefs,
479                                         size_t num_prefs) {
480   return set_algorithm_prefs(&ctx->cert->sigalgs, &ctx->cert->num_sigalgs,
481                              prefs, num_prefs);
482 }
483 
SSL_set_signing_algorithm_prefs(SSL * ssl,const uint16_t * prefs,size_t num_prefs)484 int SSL_set_signing_algorithm_prefs(SSL *ssl, const uint16_t *prefs,
485                                     size_t num_prefs) {
486   return set_algorithm_prefs(&ssl->cert->sigalgs, &ssl->cert->num_sigalgs,
487                              prefs, num_prefs);
488 }
489 
SSL_CTX_set_verify_algorithm_prefs(SSL_CTX * ctx,const uint16_t * prefs,size_t num_prefs)490 int SSL_CTX_set_verify_algorithm_prefs(SSL_CTX *ctx, const uint16_t *prefs,
491                                        size_t num_prefs) {
492   return set_algorithm_prefs(&ctx->verify_sigalgs, &ctx->num_verify_sigalgs,
493                              prefs, num_prefs);
494 }
495