1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2012-2022 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci#include <stdio.h> 11e1051a39Sopenharmony_ci#include "ssl_local.h" 12e1051a39Sopenharmony_ci#include <openssl/conf.h> 13e1051a39Sopenharmony_ci#include <openssl/objects.h> 14e1051a39Sopenharmony_ci#include <openssl/decoder.h> 15e1051a39Sopenharmony_ci#include <openssl/core_dispatch.h> 16e1051a39Sopenharmony_ci#include "internal/nelem.h" 17e1051a39Sopenharmony_ci 18e1051a39Sopenharmony_ci/* 19e1051a39Sopenharmony_ci * structure holding name tables. This is used for permitted elements in lists 20e1051a39Sopenharmony_ci * such as TLSv1. 21e1051a39Sopenharmony_ci */ 22e1051a39Sopenharmony_ci 23e1051a39Sopenharmony_citypedef struct { 24e1051a39Sopenharmony_ci const char *name; 25e1051a39Sopenharmony_ci int namelen; 26e1051a39Sopenharmony_ci unsigned int name_flags; 27e1051a39Sopenharmony_ci uint64_t option_value; 28e1051a39Sopenharmony_ci} ssl_flag_tbl; 29e1051a39Sopenharmony_ci 30e1051a39Sopenharmony_ci/* Switch table: use for single command line switches like no_tls2 */ 31e1051a39Sopenharmony_citypedef struct { 32e1051a39Sopenharmony_ci uint64_t option_value; 33e1051a39Sopenharmony_ci unsigned int name_flags; 34e1051a39Sopenharmony_ci} ssl_switch_tbl; 35e1051a39Sopenharmony_ci 36e1051a39Sopenharmony_ci/* Sense of name is inverted e.g. "TLSv1" will clear SSL_OP_NO_TLSv1 */ 37e1051a39Sopenharmony_ci#define SSL_TFLAG_INV 0x1 38e1051a39Sopenharmony_ci/* Mask for type of flag referred to */ 39e1051a39Sopenharmony_ci#define SSL_TFLAG_TYPE_MASK 0xf00 40e1051a39Sopenharmony_ci/* Flag is for options */ 41e1051a39Sopenharmony_ci#define SSL_TFLAG_OPTION 0x000 42e1051a39Sopenharmony_ci/* Flag is for cert_flags */ 43e1051a39Sopenharmony_ci#define SSL_TFLAG_CERT 0x100 44e1051a39Sopenharmony_ci/* Flag is for verify mode */ 45e1051a39Sopenharmony_ci#define SSL_TFLAG_VFY 0x200 46e1051a39Sopenharmony_ci/* Option can only be used for clients */ 47e1051a39Sopenharmony_ci#define SSL_TFLAG_CLIENT SSL_CONF_FLAG_CLIENT 48e1051a39Sopenharmony_ci/* Option can only be used for servers */ 49e1051a39Sopenharmony_ci#define SSL_TFLAG_SERVER SSL_CONF_FLAG_SERVER 50e1051a39Sopenharmony_ci#define SSL_TFLAG_BOTH (SSL_TFLAG_CLIENT|SSL_TFLAG_SERVER) 51e1051a39Sopenharmony_ci 52e1051a39Sopenharmony_ci#define SSL_FLAG_TBL(str, flag) \ 53e1051a39Sopenharmony_ci {str, (int)(sizeof(str) - 1), SSL_TFLAG_BOTH, flag} 54e1051a39Sopenharmony_ci#define SSL_FLAG_TBL_SRV(str, flag) \ 55e1051a39Sopenharmony_ci {str, (int)(sizeof(str) - 1), SSL_TFLAG_SERVER, flag} 56e1051a39Sopenharmony_ci#define SSL_FLAG_TBL_CLI(str, flag) \ 57e1051a39Sopenharmony_ci {str, (int)(sizeof(str) - 1), SSL_TFLAG_CLIENT, flag} 58e1051a39Sopenharmony_ci#define SSL_FLAG_TBL_INV(str, flag) \ 59e1051a39Sopenharmony_ci {str, (int)(sizeof(str) - 1), SSL_TFLAG_INV|SSL_TFLAG_BOTH, flag} 60e1051a39Sopenharmony_ci#define SSL_FLAG_TBL_SRV_INV(str, flag) \ 61e1051a39Sopenharmony_ci {str, (int)(sizeof(str) - 1), SSL_TFLAG_INV|SSL_TFLAG_SERVER, flag} 62e1051a39Sopenharmony_ci#define SSL_FLAG_TBL_CERT(str, flag) \ 63e1051a39Sopenharmony_ci {str, (int)(sizeof(str) - 1), SSL_TFLAG_CERT|SSL_TFLAG_BOTH, flag} 64e1051a39Sopenharmony_ci 65e1051a39Sopenharmony_ci#define SSL_FLAG_VFY_CLI(str, flag) \ 66e1051a39Sopenharmony_ci {str, (int)(sizeof(str) - 1), SSL_TFLAG_VFY | SSL_TFLAG_CLIENT, flag} 67e1051a39Sopenharmony_ci#define SSL_FLAG_VFY_SRV(str, flag) \ 68e1051a39Sopenharmony_ci {str, (int)(sizeof(str) - 1), SSL_TFLAG_VFY | SSL_TFLAG_SERVER, flag} 69e1051a39Sopenharmony_ci 70e1051a39Sopenharmony_ci/* 71e1051a39Sopenharmony_ci * Opaque structure containing SSL configuration context. 72e1051a39Sopenharmony_ci */ 73e1051a39Sopenharmony_ci 74e1051a39Sopenharmony_cistruct ssl_conf_ctx_st { 75e1051a39Sopenharmony_ci /* 76e1051a39Sopenharmony_ci * Various flags indicating (among other things) which options we will 77e1051a39Sopenharmony_ci * recognise. 78e1051a39Sopenharmony_ci */ 79e1051a39Sopenharmony_ci unsigned int flags; 80e1051a39Sopenharmony_ci /* Prefix and length of commands */ 81e1051a39Sopenharmony_ci char *prefix; 82e1051a39Sopenharmony_ci size_t prefixlen; 83e1051a39Sopenharmony_ci /* SSL_CTX or SSL structure to perform operations on */ 84e1051a39Sopenharmony_ci SSL_CTX *ctx; 85e1051a39Sopenharmony_ci SSL *ssl; 86e1051a39Sopenharmony_ci /* Pointer to SSL or SSL_CTX options field or NULL if none */ 87e1051a39Sopenharmony_ci uint64_t *poptions; 88e1051a39Sopenharmony_ci /* Certificate filenames for each type */ 89e1051a39Sopenharmony_ci char *cert_filename[SSL_PKEY_NUM]; 90e1051a39Sopenharmony_ci /* Pointer to SSL or SSL_CTX cert_flags or NULL if none */ 91e1051a39Sopenharmony_ci uint32_t *pcert_flags; 92e1051a39Sopenharmony_ci /* Pointer to SSL or SSL_CTX verify_mode or NULL if none */ 93e1051a39Sopenharmony_ci uint32_t *pvfy_flags; 94e1051a39Sopenharmony_ci /* Pointer to SSL or SSL_CTX min_version field or NULL if none */ 95e1051a39Sopenharmony_ci int *min_version; 96e1051a39Sopenharmony_ci /* Pointer to SSL or SSL_CTX max_version field or NULL if none */ 97e1051a39Sopenharmony_ci int *max_version; 98e1051a39Sopenharmony_ci /* Current flag table being worked on */ 99e1051a39Sopenharmony_ci const ssl_flag_tbl *tbl; 100e1051a39Sopenharmony_ci /* Size of table */ 101e1051a39Sopenharmony_ci size_t ntbl; 102e1051a39Sopenharmony_ci /* Client CA names */ 103e1051a39Sopenharmony_ci STACK_OF(X509_NAME) *canames; 104e1051a39Sopenharmony_ci}; 105e1051a39Sopenharmony_ci 106e1051a39Sopenharmony_cistatic void ssl_set_option(SSL_CONF_CTX *cctx, unsigned int name_flags, 107e1051a39Sopenharmony_ci uint64_t option_value, int onoff) 108e1051a39Sopenharmony_ci{ 109e1051a39Sopenharmony_ci uint32_t *pflags; 110e1051a39Sopenharmony_ci 111e1051a39Sopenharmony_ci if (cctx->poptions == NULL) 112e1051a39Sopenharmony_ci return; 113e1051a39Sopenharmony_ci if (name_flags & SSL_TFLAG_INV) 114e1051a39Sopenharmony_ci onoff ^= 1; 115e1051a39Sopenharmony_ci switch (name_flags & SSL_TFLAG_TYPE_MASK) { 116e1051a39Sopenharmony_ci 117e1051a39Sopenharmony_ci case SSL_TFLAG_CERT: 118e1051a39Sopenharmony_ci pflags = cctx->pcert_flags; 119e1051a39Sopenharmony_ci break; 120e1051a39Sopenharmony_ci 121e1051a39Sopenharmony_ci case SSL_TFLAG_VFY: 122e1051a39Sopenharmony_ci pflags = cctx->pvfy_flags; 123e1051a39Sopenharmony_ci break; 124e1051a39Sopenharmony_ci 125e1051a39Sopenharmony_ci case SSL_TFLAG_OPTION: 126e1051a39Sopenharmony_ci if (onoff) 127e1051a39Sopenharmony_ci *cctx->poptions |= option_value; 128e1051a39Sopenharmony_ci else 129e1051a39Sopenharmony_ci *cctx->poptions &= ~option_value; 130e1051a39Sopenharmony_ci return; 131e1051a39Sopenharmony_ci 132e1051a39Sopenharmony_ci default: 133e1051a39Sopenharmony_ci return; 134e1051a39Sopenharmony_ci 135e1051a39Sopenharmony_ci } 136e1051a39Sopenharmony_ci if (onoff) 137e1051a39Sopenharmony_ci *pflags |= option_value; 138e1051a39Sopenharmony_ci else 139e1051a39Sopenharmony_ci *pflags &= ~option_value; 140e1051a39Sopenharmony_ci} 141e1051a39Sopenharmony_ci 142e1051a39Sopenharmony_cistatic int ssl_match_option(SSL_CONF_CTX *cctx, const ssl_flag_tbl *tbl, 143e1051a39Sopenharmony_ci const char *name, int namelen, int onoff) 144e1051a39Sopenharmony_ci{ 145e1051a39Sopenharmony_ci /* If name not relevant for context skip */ 146e1051a39Sopenharmony_ci if (!(cctx->flags & tbl->name_flags & SSL_TFLAG_BOTH)) 147e1051a39Sopenharmony_ci return 0; 148e1051a39Sopenharmony_ci if (namelen == -1) { 149e1051a39Sopenharmony_ci if (strcmp(tbl->name, name)) 150e1051a39Sopenharmony_ci return 0; 151e1051a39Sopenharmony_ci } else if (tbl->namelen != namelen 152e1051a39Sopenharmony_ci || OPENSSL_strncasecmp(tbl->name, name, namelen)) 153e1051a39Sopenharmony_ci return 0; 154e1051a39Sopenharmony_ci ssl_set_option(cctx, tbl->name_flags, tbl->option_value, onoff); 155e1051a39Sopenharmony_ci return 1; 156e1051a39Sopenharmony_ci} 157e1051a39Sopenharmony_ci 158e1051a39Sopenharmony_cistatic int ssl_set_option_list(const char *elem, int len, void *usr) 159e1051a39Sopenharmony_ci{ 160e1051a39Sopenharmony_ci SSL_CONF_CTX *cctx = usr; 161e1051a39Sopenharmony_ci size_t i; 162e1051a39Sopenharmony_ci const ssl_flag_tbl *tbl; 163e1051a39Sopenharmony_ci int onoff = 1; 164e1051a39Sopenharmony_ci /* 165e1051a39Sopenharmony_ci * len == -1 indicates not being called in list context, just for single 166e1051a39Sopenharmony_ci * command line switches, so don't allow +, -. 167e1051a39Sopenharmony_ci */ 168e1051a39Sopenharmony_ci if (elem == NULL) 169e1051a39Sopenharmony_ci return 0; 170e1051a39Sopenharmony_ci if (len != -1) { 171e1051a39Sopenharmony_ci if (*elem == '+') { 172e1051a39Sopenharmony_ci elem++; 173e1051a39Sopenharmony_ci len--; 174e1051a39Sopenharmony_ci onoff = 1; 175e1051a39Sopenharmony_ci } else if (*elem == '-') { 176e1051a39Sopenharmony_ci elem++; 177e1051a39Sopenharmony_ci len--; 178e1051a39Sopenharmony_ci onoff = 0; 179e1051a39Sopenharmony_ci } 180e1051a39Sopenharmony_ci } 181e1051a39Sopenharmony_ci for (i = 0, tbl = cctx->tbl; i < cctx->ntbl; i++, tbl++) { 182e1051a39Sopenharmony_ci if (ssl_match_option(cctx, tbl, elem, len, onoff)) 183e1051a39Sopenharmony_ci return 1; 184e1051a39Sopenharmony_ci } 185e1051a39Sopenharmony_ci return 0; 186e1051a39Sopenharmony_ci} 187e1051a39Sopenharmony_ci 188e1051a39Sopenharmony_ci/* Set supported signature algorithms */ 189e1051a39Sopenharmony_cistatic int cmd_SignatureAlgorithms(SSL_CONF_CTX *cctx, const char *value) 190e1051a39Sopenharmony_ci{ 191e1051a39Sopenharmony_ci int rv; 192e1051a39Sopenharmony_ci if (cctx->ssl) 193e1051a39Sopenharmony_ci rv = SSL_set1_sigalgs_list(cctx->ssl, value); 194e1051a39Sopenharmony_ci /* NB: ctx == NULL performs syntax checking only */ 195e1051a39Sopenharmony_ci else 196e1051a39Sopenharmony_ci rv = SSL_CTX_set1_sigalgs_list(cctx->ctx, value); 197e1051a39Sopenharmony_ci return rv > 0; 198e1051a39Sopenharmony_ci} 199e1051a39Sopenharmony_ci 200e1051a39Sopenharmony_ci/* Set supported client signature algorithms */ 201e1051a39Sopenharmony_cistatic int cmd_ClientSignatureAlgorithms(SSL_CONF_CTX *cctx, const char *value) 202e1051a39Sopenharmony_ci{ 203e1051a39Sopenharmony_ci int rv; 204e1051a39Sopenharmony_ci if (cctx->ssl) 205e1051a39Sopenharmony_ci rv = SSL_set1_client_sigalgs_list(cctx->ssl, value); 206e1051a39Sopenharmony_ci /* NB: ctx == NULL performs syntax checking only */ 207e1051a39Sopenharmony_ci else 208e1051a39Sopenharmony_ci rv = SSL_CTX_set1_client_sigalgs_list(cctx->ctx, value); 209e1051a39Sopenharmony_ci return rv > 0; 210e1051a39Sopenharmony_ci} 211e1051a39Sopenharmony_ci 212e1051a39Sopenharmony_cistatic int cmd_Groups(SSL_CONF_CTX *cctx, const char *value) 213e1051a39Sopenharmony_ci{ 214e1051a39Sopenharmony_ci int rv; 215e1051a39Sopenharmony_ci if (cctx->ssl) 216e1051a39Sopenharmony_ci rv = SSL_set1_groups_list(cctx->ssl, value); 217e1051a39Sopenharmony_ci /* NB: ctx == NULL performs syntax checking only */ 218e1051a39Sopenharmony_ci else 219e1051a39Sopenharmony_ci rv = SSL_CTX_set1_groups_list(cctx->ctx, value); 220e1051a39Sopenharmony_ci return rv > 0; 221e1051a39Sopenharmony_ci} 222e1051a39Sopenharmony_ci 223e1051a39Sopenharmony_ci/* This is the old name for cmd_Groups - retained for backwards compatibility */ 224e1051a39Sopenharmony_cistatic int cmd_Curves(SSL_CONF_CTX *cctx, const char *value) 225e1051a39Sopenharmony_ci{ 226e1051a39Sopenharmony_ci return cmd_Groups(cctx, value); 227e1051a39Sopenharmony_ci} 228e1051a39Sopenharmony_ci 229e1051a39Sopenharmony_ci/* ECDH temporary parameters */ 230e1051a39Sopenharmony_cistatic int cmd_ECDHParameters(SSL_CONF_CTX *cctx, const char *value) 231e1051a39Sopenharmony_ci{ 232e1051a39Sopenharmony_ci int rv = 1; 233e1051a39Sopenharmony_ci 234e1051a39Sopenharmony_ci /* Ignore values supported by 1.0.2 for the automatic selection */ 235e1051a39Sopenharmony_ci if ((cctx->flags & SSL_CONF_FLAG_FILE) 236e1051a39Sopenharmony_ci && (OPENSSL_strcasecmp(value, "+automatic") == 0 237e1051a39Sopenharmony_ci || OPENSSL_strcasecmp(value, "automatic") == 0)) 238e1051a39Sopenharmony_ci return 1; 239e1051a39Sopenharmony_ci if ((cctx->flags & SSL_CONF_FLAG_CMDLINE) && 240e1051a39Sopenharmony_ci strcmp(value, "auto") == 0) 241e1051a39Sopenharmony_ci return 1; 242e1051a39Sopenharmony_ci 243e1051a39Sopenharmony_ci /* ECDHParameters accepts a single group name */ 244e1051a39Sopenharmony_ci if (strstr(value, ":") != NULL) 245e1051a39Sopenharmony_ci return 0; 246e1051a39Sopenharmony_ci 247e1051a39Sopenharmony_ci if (cctx->ctx) 248e1051a39Sopenharmony_ci rv = SSL_CTX_set1_groups_list(cctx->ctx, value); 249e1051a39Sopenharmony_ci else if (cctx->ssl) 250e1051a39Sopenharmony_ci rv = SSL_set1_groups_list(cctx->ssl, value); 251e1051a39Sopenharmony_ci 252e1051a39Sopenharmony_ci return rv > 0; 253e1051a39Sopenharmony_ci} 254e1051a39Sopenharmony_ci 255e1051a39Sopenharmony_cistatic int cmd_CipherString(SSL_CONF_CTX *cctx, const char *value) 256e1051a39Sopenharmony_ci{ 257e1051a39Sopenharmony_ci int rv = 1; 258e1051a39Sopenharmony_ci 259e1051a39Sopenharmony_ci if (cctx->ctx) 260e1051a39Sopenharmony_ci rv = SSL_CTX_set_cipher_list(cctx->ctx, value); 261e1051a39Sopenharmony_ci if (cctx->ssl) 262e1051a39Sopenharmony_ci rv = SSL_set_cipher_list(cctx->ssl, value); 263e1051a39Sopenharmony_ci return rv > 0; 264e1051a39Sopenharmony_ci} 265e1051a39Sopenharmony_ci 266e1051a39Sopenharmony_cistatic int cmd_Ciphersuites(SSL_CONF_CTX *cctx, const char *value) 267e1051a39Sopenharmony_ci{ 268e1051a39Sopenharmony_ci int rv = 1; 269e1051a39Sopenharmony_ci 270e1051a39Sopenharmony_ci if (cctx->ctx) 271e1051a39Sopenharmony_ci rv = SSL_CTX_set_ciphersuites(cctx->ctx, value); 272e1051a39Sopenharmony_ci if (cctx->ssl) 273e1051a39Sopenharmony_ci rv = SSL_set_ciphersuites(cctx->ssl, value); 274e1051a39Sopenharmony_ci return rv > 0; 275e1051a39Sopenharmony_ci} 276e1051a39Sopenharmony_ci 277e1051a39Sopenharmony_cistatic int cmd_Protocol(SSL_CONF_CTX *cctx, const char *value) 278e1051a39Sopenharmony_ci{ 279e1051a39Sopenharmony_ci static const ssl_flag_tbl ssl_protocol_list[] = { 280e1051a39Sopenharmony_ci SSL_FLAG_TBL_INV("ALL", SSL_OP_NO_SSL_MASK), 281e1051a39Sopenharmony_ci SSL_FLAG_TBL_INV("SSLv2", SSL_OP_NO_SSLv2), 282e1051a39Sopenharmony_ci SSL_FLAG_TBL_INV("SSLv3", SSL_OP_NO_SSLv3), 283e1051a39Sopenharmony_ci SSL_FLAG_TBL_INV("TLSv1", SSL_OP_NO_TLSv1), 284e1051a39Sopenharmony_ci SSL_FLAG_TBL_INV("TLSv1.1", SSL_OP_NO_TLSv1_1), 285e1051a39Sopenharmony_ci SSL_FLAG_TBL_INV("TLSv1.2", SSL_OP_NO_TLSv1_2), 286e1051a39Sopenharmony_ci SSL_FLAG_TBL_INV("TLSv1.3", SSL_OP_NO_TLSv1_3), 287e1051a39Sopenharmony_ci SSL_FLAG_TBL_INV("DTLSv1", SSL_OP_NO_DTLSv1), 288e1051a39Sopenharmony_ci SSL_FLAG_TBL_INV("DTLSv1.2", SSL_OP_NO_DTLSv1_2) 289e1051a39Sopenharmony_ci }; 290e1051a39Sopenharmony_ci cctx->tbl = ssl_protocol_list; 291e1051a39Sopenharmony_ci cctx->ntbl = OSSL_NELEM(ssl_protocol_list); 292e1051a39Sopenharmony_ci return CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx); 293e1051a39Sopenharmony_ci} 294e1051a39Sopenharmony_ci 295e1051a39Sopenharmony_ci/* 296e1051a39Sopenharmony_ci * protocol_from_string - converts a protocol version string to a number 297e1051a39Sopenharmony_ci * 298e1051a39Sopenharmony_ci * Returns -1 on failure or the version on success 299e1051a39Sopenharmony_ci */ 300e1051a39Sopenharmony_cistatic int protocol_from_string(const char *value) 301e1051a39Sopenharmony_ci{ 302e1051a39Sopenharmony_ci struct protocol_versions { 303e1051a39Sopenharmony_ci const char *name; 304e1051a39Sopenharmony_ci int version; 305e1051a39Sopenharmony_ci }; 306e1051a39Sopenharmony_ci /* 307e1051a39Sopenharmony_ci * Note: To avoid breaking previously valid configurations, we must retain 308e1051a39Sopenharmony_ci * legacy entries in this table even if the underlying protocol is no 309e1051a39Sopenharmony_ci * longer supported. This also means that the constants SSL3_VERSION, ... 310e1051a39Sopenharmony_ci * need to be retained indefinitely. This table can only grow, never 311e1051a39Sopenharmony_ci * shrink. 312e1051a39Sopenharmony_ci */ 313e1051a39Sopenharmony_ci static const struct protocol_versions versions[] = { 314e1051a39Sopenharmony_ci {"None", 0}, 315e1051a39Sopenharmony_ci {"SSLv3", SSL3_VERSION}, 316e1051a39Sopenharmony_ci {"TLSv1", TLS1_VERSION}, 317e1051a39Sopenharmony_ci {"TLSv1.1", TLS1_1_VERSION}, 318e1051a39Sopenharmony_ci {"TLSv1.2", TLS1_2_VERSION}, 319e1051a39Sopenharmony_ci {"TLSv1.3", TLS1_3_VERSION}, 320e1051a39Sopenharmony_ci {"DTLSv1", DTLS1_VERSION}, 321e1051a39Sopenharmony_ci {"DTLSv1.2", DTLS1_2_VERSION} 322e1051a39Sopenharmony_ci }; 323e1051a39Sopenharmony_ci size_t i; 324e1051a39Sopenharmony_ci size_t n = OSSL_NELEM(versions); 325e1051a39Sopenharmony_ci 326e1051a39Sopenharmony_ci for (i = 0; i < n; i++) 327e1051a39Sopenharmony_ci if (strcmp(versions[i].name, value) == 0) 328e1051a39Sopenharmony_ci return versions[i].version; 329e1051a39Sopenharmony_ci return -1; 330e1051a39Sopenharmony_ci} 331e1051a39Sopenharmony_ci 332e1051a39Sopenharmony_cistatic int min_max_proto(SSL_CONF_CTX *cctx, const char *value, int *bound) 333e1051a39Sopenharmony_ci{ 334e1051a39Sopenharmony_ci int method_version; 335e1051a39Sopenharmony_ci int new_version; 336e1051a39Sopenharmony_ci 337e1051a39Sopenharmony_ci if (cctx->ctx != NULL) 338e1051a39Sopenharmony_ci method_version = cctx->ctx->method->version; 339e1051a39Sopenharmony_ci else if (cctx->ssl != NULL) 340e1051a39Sopenharmony_ci method_version = cctx->ssl->ctx->method->version; 341e1051a39Sopenharmony_ci else 342e1051a39Sopenharmony_ci return 0; 343e1051a39Sopenharmony_ci if ((new_version = protocol_from_string(value)) < 0) 344e1051a39Sopenharmony_ci return 0; 345e1051a39Sopenharmony_ci return ssl_set_version_bound(method_version, new_version, bound); 346e1051a39Sopenharmony_ci} 347e1051a39Sopenharmony_ci 348e1051a39Sopenharmony_ci/* 349e1051a39Sopenharmony_ci * cmd_MinProtocol - Set min protocol version 350e1051a39Sopenharmony_ci * @cctx: config structure to save settings in 351e1051a39Sopenharmony_ci * @value: The min protocol version in string form 352e1051a39Sopenharmony_ci * 353e1051a39Sopenharmony_ci * Returns 1 on success and 0 on failure. 354e1051a39Sopenharmony_ci */ 355e1051a39Sopenharmony_cistatic int cmd_MinProtocol(SSL_CONF_CTX *cctx, const char *value) 356e1051a39Sopenharmony_ci{ 357e1051a39Sopenharmony_ci return min_max_proto(cctx, value, cctx->min_version); 358e1051a39Sopenharmony_ci} 359e1051a39Sopenharmony_ci 360e1051a39Sopenharmony_ci/* 361e1051a39Sopenharmony_ci * cmd_MaxProtocol - Set max protocol version 362e1051a39Sopenharmony_ci * @cctx: config structure to save settings in 363e1051a39Sopenharmony_ci * @value: The max protocol version in string form 364e1051a39Sopenharmony_ci * 365e1051a39Sopenharmony_ci * Returns 1 on success and 0 on failure. 366e1051a39Sopenharmony_ci */ 367e1051a39Sopenharmony_cistatic int cmd_MaxProtocol(SSL_CONF_CTX *cctx, const char *value) 368e1051a39Sopenharmony_ci{ 369e1051a39Sopenharmony_ci return min_max_proto(cctx, value, cctx->max_version); 370e1051a39Sopenharmony_ci} 371e1051a39Sopenharmony_ci 372e1051a39Sopenharmony_cistatic int cmd_Options(SSL_CONF_CTX *cctx, const char *value) 373e1051a39Sopenharmony_ci{ 374e1051a39Sopenharmony_ci static const ssl_flag_tbl ssl_option_list[] = { 375e1051a39Sopenharmony_ci SSL_FLAG_TBL_INV("SessionTicket", SSL_OP_NO_TICKET), 376e1051a39Sopenharmony_ci SSL_FLAG_TBL_INV("EmptyFragments", 377e1051a39Sopenharmony_ci SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS), 378e1051a39Sopenharmony_ci SSL_FLAG_TBL("Bugs", SSL_OP_ALL), 379e1051a39Sopenharmony_ci SSL_FLAG_TBL_INV("Compression", SSL_OP_NO_COMPRESSION), 380e1051a39Sopenharmony_ci SSL_FLAG_TBL_SRV("ServerPreference", SSL_OP_CIPHER_SERVER_PREFERENCE), 381e1051a39Sopenharmony_ci SSL_FLAG_TBL_SRV("NoResumptionOnRenegotiation", 382e1051a39Sopenharmony_ci SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION), 383e1051a39Sopenharmony_ci SSL_FLAG_TBL_SRV("DHSingle", SSL_OP_SINGLE_DH_USE), 384e1051a39Sopenharmony_ci SSL_FLAG_TBL_SRV("ECDHSingle", SSL_OP_SINGLE_ECDH_USE), 385e1051a39Sopenharmony_ci SSL_FLAG_TBL("UnsafeLegacyRenegotiation", 386e1051a39Sopenharmony_ci SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION), 387e1051a39Sopenharmony_ci SSL_FLAG_TBL("UnsafeLegacyServerConnect", 388e1051a39Sopenharmony_ci SSL_OP_LEGACY_SERVER_CONNECT), 389e1051a39Sopenharmony_ci SSL_FLAG_TBL("ClientRenegotiation", 390e1051a39Sopenharmony_ci SSL_OP_ALLOW_CLIENT_RENEGOTIATION), 391e1051a39Sopenharmony_ci SSL_FLAG_TBL_INV("EncryptThenMac", SSL_OP_NO_ENCRYPT_THEN_MAC), 392e1051a39Sopenharmony_ci SSL_FLAG_TBL("NoRenegotiation", SSL_OP_NO_RENEGOTIATION), 393e1051a39Sopenharmony_ci SSL_FLAG_TBL("AllowNoDHEKEX", SSL_OP_ALLOW_NO_DHE_KEX), 394e1051a39Sopenharmony_ci SSL_FLAG_TBL("PrioritizeChaCha", SSL_OP_PRIORITIZE_CHACHA), 395e1051a39Sopenharmony_ci SSL_FLAG_TBL("MiddleboxCompat", SSL_OP_ENABLE_MIDDLEBOX_COMPAT), 396e1051a39Sopenharmony_ci SSL_FLAG_TBL_INV("AntiReplay", SSL_OP_NO_ANTI_REPLAY), 397e1051a39Sopenharmony_ci SSL_FLAG_TBL_INV("ExtendedMasterSecret", SSL_OP_NO_EXTENDED_MASTER_SECRET), 398e1051a39Sopenharmony_ci SSL_FLAG_TBL_INV("CANames", SSL_OP_DISABLE_TLSEXT_CA_NAMES), 399e1051a39Sopenharmony_ci SSL_FLAG_TBL("KTLS", SSL_OP_ENABLE_KTLS) 400e1051a39Sopenharmony_ci }; 401e1051a39Sopenharmony_ci if (value == NULL) 402e1051a39Sopenharmony_ci return -3; 403e1051a39Sopenharmony_ci cctx->tbl = ssl_option_list; 404e1051a39Sopenharmony_ci cctx->ntbl = OSSL_NELEM(ssl_option_list); 405e1051a39Sopenharmony_ci return CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx); 406e1051a39Sopenharmony_ci} 407e1051a39Sopenharmony_ci 408e1051a39Sopenharmony_cistatic int cmd_VerifyMode(SSL_CONF_CTX *cctx, const char *value) 409e1051a39Sopenharmony_ci{ 410e1051a39Sopenharmony_ci static const ssl_flag_tbl ssl_vfy_list[] = { 411e1051a39Sopenharmony_ci SSL_FLAG_VFY_CLI("Peer", SSL_VERIFY_PEER), 412e1051a39Sopenharmony_ci SSL_FLAG_VFY_SRV("Request", SSL_VERIFY_PEER), 413e1051a39Sopenharmony_ci SSL_FLAG_VFY_SRV("Require", 414e1051a39Sopenharmony_ci SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT), 415e1051a39Sopenharmony_ci SSL_FLAG_VFY_SRV("Once", SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE), 416e1051a39Sopenharmony_ci SSL_FLAG_VFY_SRV("RequestPostHandshake", 417e1051a39Sopenharmony_ci SSL_VERIFY_PEER | SSL_VERIFY_POST_HANDSHAKE), 418e1051a39Sopenharmony_ci SSL_FLAG_VFY_SRV("RequirePostHandshake", 419e1051a39Sopenharmony_ci SSL_VERIFY_PEER | SSL_VERIFY_POST_HANDSHAKE | 420e1051a39Sopenharmony_ci SSL_VERIFY_FAIL_IF_NO_PEER_CERT), 421e1051a39Sopenharmony_ci }; 422e1051a39Sopenharmony_ci if (value == NULL) 423e1051a39Sopenharmony_ci return -3; 424e1051a39Sopenharmony_ci cctx->tbl = ssl_vfy_list; 425e1051a39Sopenharmony_ci cctx->ntbl = OSSL_NELEM(ssl_vfy_list); 426e1051a39Sopenharmony_ci return CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx); 427e1051a39Sopenharmony_ci} 428e1051a39Sopenharmony_ci 429e1051a39Sopenharmony_cistatic int cmd_Certificate(SSL_CONF_CTX *cctx, const char *value) 430e1051a39Sopenharmony_ci{ 431e1051a39Sopenharmony_ci int rv = 1; 432e1051a39Sopenharmony_ci CERT *c = NULL; 433e1051a39Sopenharmony_ci if (cctx->ctx) { 434e1051a39Sopenharmony_ci rv = SSL_CTX_use_certificate_chain_file(cctx->ctx, value); 435e1051a39Sopenharmony_ci c = cctx->ctx->cert; 436e1051a39Sopenharmony_ci } 437e1051a39Sopenharmony_ci if (cctx->ssl) { 438e1051a39Sopenharmony_ci rv = SSL_use_certificate_chain_file(cctx->ssl, value); 439e1051a39Sopenharmony_ci c = cctx->ssl->cert; 440e1051a39Sopenharmony_ci } 441e1051a39Sopenharmony_ci if (rv > 0 && c && cctx->flags & SSL_CONF_FLAG_REQUIRE_PRIVATE) { 442e1051a39Sopenharmony_ci char **pfilename = &cctx->cert_filename[c->key - c->pkeys]; 443e1051a39Sopenharmony_ci OPENSSL_free(*pfilename); 444e1051a39Sopenharmony_ci *pfilename = OPENSSL_strdup(value); 445e1051a39Sopenharmony_ci if (*pfilename == NULL) 446e1051a39Sopenharmony_ci rv = 0; 447e1051a39Sopenharmony_ci } 448e1051a39Sopenharmony_ci 449e1051a39Sopenharmony_ci return rv > 0; 450e1051a39Sopenharmony_ci} 451e1051a39Sopenharmony_ci 452e1051a39Sopenharmony_cistatic int cmd_PrivateKey(SSL_CONF_CTX *cctx, const char *value) 453e1051a39Sopenharmony_ci{ 454e1051a39Sopenharmony_ci int rv = 1; 455e1051a39Sopenharmony_ci if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE)) 456e1051a39Sopenharmony_ci return -2; 457e1051a39Sopenharmony_ci if (cctx->ctx) 458e1051a39Sopenharmony_ci rv = SSL_CTX_use_PrivateKey_file(cctx->ctx, value, SSL_FILETYPE_PEM); 459e1051a39Sopenharmony_ci if (cctx->ssl) 460e1051a39Sopenharmony_ci rv = SSL_use_PrivateKey_file(cctx->ssl, value, SSL_FILETYPE_PEM); 461e1051a39Sopenharmony_ci return rv > 0; 462e1051a39Sopenharmony_ci} 463e1051a39Sopenharmony_ci 464e1051a39Sopenharmony_cistatic int cmd_ServerInfoFile(SSL_CONF_CTX *cctx, const char *value) 465e1051a39Sopenharmony_ci{ 466e1051a39Sopenharmony_ci int rv = 1; 467e1051a39Sopenharmony_ci if (cctx->ctx) 468e1051a39Sopenharmony_ci rv = SSL_CTX_use_serverinfo_file(cctx->ctx, value); 469e1051a39Sopenharmony_ci return rv > 0; 470e1051a39Sopenharmony_ci} 471e1051a39Sopenharmony_ci 472e1051a39Sopenharmony_cistatic int do_store(SSL_CONF_CTX *cctx, 473e1051a39Sopenharmony_ci const char *CAfile, const char *CApath, const char *CAstore, 474e1051a39Sopenharmony_ci int verify_store) 475e1051a39Sopenharmony_ci{ 476e1051a39Sopenharmony_ci CERT *cert; 477e1051a39Sopenharmony_ci X509_STORE **st; 478e1051a39Sopenharmony_ci SSL_CTX *ctx; 479e1051a39Sopenharmony_ci OSSL_LIB_CTX *libctx = NULL; 480e1051a39Sopenharmony_ci const char *propq = NULL; 481e1051a39Sopenharmony_ci 482e1051a39Sopenharmony_ci if (cctx->ctx != NULL) { 483e1051a39Sopenharmony_ci cert = cctx->ctx->cert; 484e1051a39Sopenharmony_ci ctx = cctx->ctx; 485e1051a39Sopenharmony_ci } else if (cctx->ssl != NULL) { 486e1051a39Sopenharmony_ci cert = cctx->ssl->cert; 487e1051a39Sopenharmony_ci ctx = cctx->ssl->ctx; 488e1051a39Sopenharmony_ci } else { 489e1051a39Sopenharmony_ci return 1; 490e1051a39Sopenharmony_ci } 491e1051a39Sopenharmony_ci if (ctx != NULL) { 492e1051a39Sopenharmony_ci libctx = ctx->libctx; 493e1051a39Sopenharmony_ci propq = ctx->propq; 494e1051a39Sopenharmony_ci } 495e1051a39Sopenharmony_ci st = verify_store ? &cert->verify_store : &cert->chain_store; 496e1051a39Sopenharmony_ci if (*st == NULL) { 497e1051a39Sopenharmony_ci *st = X509_STORE_new(); 498e1051a39Sopenharmony_ci if (*st == NULL) 499e1051a39Sopenharmony_ci return 0; 500e1051a39Sopenharmony_ci } 501e1051a39Sopenharmony_ci 502e1051a39Sopenharmony_ci if (CAfile != NULL && !X509_STORE_load_file_ex(*st, CAfile, libctx, propq)) 503e1051a39Sopenharmony_ci return 0; 504e1051a39Sopenharmony_ci if (CApath != NULL && !X509_STORE_load_path(*st, CApath)) 505e1051a39Sopenharmony_ci return 0; 506e1051a39Sopenharmony_ci if (CAstore != NULL && !X509_STORE_load_store_ex(*st, CAstore, libctx, 507e1051a39Sopenharmony_ci propq)) 508e1051a39Sopenharmony_ci return 0; 509e1051a39Sopenharmony_ci return 1; 510e1051a39Sopenharmony_ci} 511e1051a39Sopenharmony_ci 512e1051a39Sopenharmony_cistatic int cmd_ChainCAPath(SSL_CONF_CTX *cctx, const char *value) 513e1051a39Sopenharmony_ci{ 514e1051a39Sopenharmony_ci return do_store(cctx, NULL, value, NULL, 0); 515e1051a39Sopenharmony_ci} 516e1051a39Sopenharmony_ci 517e1051a39Sopenharmony_cistatic int cmd_ChainCAFile(SSL_CONF_CTX *cctx, const char *value) 518e1051a39Sopenharmony_ci{ 519e1051a39Sopenharmony_ci return do_store(cctx, value, NULL, NULL, 0); 520e1051a39Sopenharmony_ci} 521e1051a39Sopenharmony_ci 522e1051a39Sopenharmony_cistatic int cmd_ChainCAStore(SSL_CONF_CTX *cctx, const char *value) 523e1051a39Sopenharmony_ci{ 524e1051a39Sopenharmony_ci return do_store(cctx, NULL, NULL, value, 0); 525e1051a39Sopenharmony_ci} 526e1051a39Sopenharmony_ci 527e1051a39Sopenharmony_cistatic int cmd_VerifyCAPath(SSL_CONF_CTX *cctx, const char *value) 528e1051a39Sopenharmony_ci{ 529e1051a39Sopenharmony_ci return do_store(cctx, NULL, value, NULL, 1); 530e1051a39Sopenharmony_ci} 531e1051a39Sopenharmony_ci 532e1051a39Sopenharmony_cistatic int cmd_VerifyCAFile(SSL_CONF_CTX *cctx, const char *value) 533e1051a39Sopenharmony_ci{ 534e1051a39Sopenharmony_ci return do_store(cctx, value, NULL, NULL, 1); 535e1051a39Sopenharmony_ci} 536e1051a39Sopenharmony_ci 537e1051a39Sopenharmony_cistatic int cmd_VerifyCAStore(SSL_CONF_CTX *cctx, const char *value) 538e1051a39Sopenharmony_ci{ 539e1051a39Sopenharmony_ci return do_store(cctx, NULL, NULL, value, 1); 540e1051a39Sopenharmony_ci} 541e1051a39Sopenharmony_ci 542e1051a39Sopenharmony_cistatic int cmd_RequestCAFile(SSL_CONF_CTX *cctx, const char *value) 543e1051a39Sopenharmony_ci{ 544e1051a39Sopenharmony_ci if (cctx->canames == NULL) 545e1051a39Sopenharmony_ci cctx->canames = sk_X509_NAME_new_null(); 546e1051a39Sopenharmony_ci if (cctx->canames == NULL) 547e1051a39Sopenharmony_ci return 0; 548e1051a39Sopenharmony_ci return SSL_add_file_cert_subjects_to_stack(cctx->canames, value); 549e1051a39Sopenharmony_ci} 550e1051a39Sopenharmony_ci 551e1051a39Sopenharmony_cistatic int cmd_ClientCAFile(SSL_CONF_CTX *cctx, const char *value) 552e1051a39Sopenharmony_ci{ 553e1051a39Sopenharmony_ci return cmd_RequestCAFile(cctx, value); 554e1051a39Sopenharmony_ci} 555e1051a39Sopenharmony_ci 556e1051a39Sopenharmony_cistatic int cmd_RequestCAPath(SSL_CONF_CTX *cctx, const char *value) 557e1051a39Sopenharmony_ci{ 558e1051a39Sopenharmony_ci if (cctx->canames == NULL) 559e1051a39Sopenharmony_ci cctx->canames = sk_X509_NAME_new_null(); 560e1051a39Sopenharmony_ci if (cctx->canames == NULL) 561e1051a39Sopenharmony_ci return 0; 562e1051a39Sopenharmony_ci return SSL_add_dir_cert_subjects_to_stack(cctx->canames, value); 563e1051a39Sopenharmony_ci} 564e1051a39Sopenharmony_ci 565e1051a39Sopenharmony_cistatic int cmd_ClientCAPath(SSL_CONF_CTX *cctx, const char *value) 566e1051a39Sopenharmony_ci{ 567e1051a39Sopenharmony_ci return cmd_RequestCAPath(cctx, value); 568e1051a39Sopenharmony_ci} 569e1051a39Sopenharmony_ci 570e1051a39Sopenharmony_cistatic int cmd_RequestCAStore(SSL_CONF_CTX *cctx, const char *value) 571e1051a39Sopenharmony_ci{ 572e1051a39Sopenharmony_ci if (cctx->canames == NULL) 573e1051a39Sopenharmony_ci cctx->canames = sk_X509_NAME_new_null(); 574e1051a39Sopenharmony_ci if (cctx->canames == NULL) 575e1051a39Sopenharmony_ci return 0; 576e1051a39Sopenharmony_ci return SSL_add_store_cert_subjects_to_stack(cctx->canames, value); 577e1051a39Sopenharmony_ci} 578e1051a39Sopenharmony_ci 579e1051a39Sopenharmony_cistatic int cmd_ClientCAStore(SSL_CONF_CTX *cctx, const char *value) 580e1051a39Sopenharmony_ci{ 581e1051a39Sopenharmony_ci return cmd_RequestCAStore(cctx, value); 582e1051a39Sopenharmony_ci} 583e1051a39Sopenharmony_ci 584e1051a39Sopenharmony_cistatic int cmd_DHParameters(SSL_CONF_CTX *cctx, const char *value) 585e1051a39Sopenharmony_ci{ 586e1051a39Sopenharmony_ci int rv = 0; 587e1051a39Sopenharmony_ci EVP_PKEY *dhpkey = NULL; 588e1051a39Sopenharmony_ci BIO *in = NULL; 589e1051a39Sopenharmony_ci SSL_CTX *sslctx = (cctx->ssl != NULL) ? cctx->ssl->ctx : cctx->ctx; 590e1051a39Sopenharmony_ci OSSL_DECODER_CTX *decoderctx = NULL; 591e1051a39Sopenharmony_ci 592e1051a39Sopenharmony_ci if (cctx->ctx != NULL || cctx->ssl != NULL) { 593e1051a39Sopenharmony_ci in = BIO_new(BIO_s_file()); 594e1051a39Sopenharmony_ci if (in == NULL) 595e1051a39Sopenharmony_ci goto end; 596e1051a39Sopenharmony_ci if (BIO_read_filename(in, value) <= 0) 597e1051a39Sopenharmony_ci goto end; 598e1051a39Sopenharmony_ci 599e1051a39Sopenharmony_ci decoderctx 600e1051a39Sopenharmony_ci = OSSL_DECODER_CTX_new_for_pkey(&dhpkey, "PEM", NULL, "DH", 601e1051a39Sopenharmony_ci OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS, 602e1051a39Sopenharmony_ci sslctx->libctx, sslctx->propq); 603e1051a39Sopenharmony_ci if (decoderctx == NULL) 604e1051a39Sopenharmony_ci goto end; 605e1051a39Sopenharmony_ci ERR_set_mark(); 606e1051a39Sopenharmony_ci while (!OSSL_DECODER_from_bio(decoderctx, in) 607e1051a39Sopenharmony_ci && dhpkey == NULL 608e1051a39Sopenharmony_ci && !BIO_eof(in)); 609e1051a39Sopenharmony_ci OSSL_DECODER_CTX_free(decoderctx); 610e1051a39Sopenharmony_ci 611e1051a39Sopenharmony_ci if (dhpkey == NULL) { 612e1051a39Sopenharmony_ci ERR_clear_last_mark(); 613e1051a39Sopenharmony_ci goto end; 614e1051a39Sopenharmony_ci } 615e1051a39Sopenharmony_ci ERR_pop_to_mark(); 616e1051a39Sopenharmony_ci } else { 617e1051a39Sopenharmony_ci return 1; 618e1051a39Sopenharmony_ci } 619e1051a39Sopenharmony_ci 620e1051a39Sopenharmony_ci if (cctx->ctx != NULL) { 621e1051a39Sopenharmony_ci if ((rv = SSL_CTX_set0_tmp_dh_pkey(cctx->ctx, dhpkey)) > 0) 622e1051a39Sopenharmony_ci dhpkey = NULL; 623e1051a39Sopenharmony_ci } 624e1051a39Sopenharmony_ci if (cctx->ssl != NULL) { 625e1051a39Sopenharmony_ci if ((rv = SSL_set0_tmp_dh_pkey(cctx->ssl, dhpkey)) > 0) 626e1051a39Sopenharmony_ci dhpkey = NULL; 627e1051a39Sopenharmony_ci } 628e1051a39Sopenharmony_ci end: 629e1051a39Sopenharmony_ci EVP_PKEY_free(dhpkey); 630e1051a39Sopenharmony_ci BIO_free(in); 631e1051a39Sopenharmony_ci return rv > 0; 632e1051a39Sopenharmony_ci} 633e1051a39Sopenharmony_ci 634e1051a39Sopenharmony_cistatic int cmd_RecordPadding(SSL_CONF_CTX *cctx, const char *value) 635e1051a39Sopenharmony_ci{ 636e1051a39Sopenharmony_ci int rv = 0; 637e1051a39Sopenharmony_ci int block_size = atoi(value); 638e1051a39Sopenharmony_ci 639e1051a39Sopenharmony_ci /* 640e1051a39Sopenharmony_ci * All we care about is a non-negative value, 641e1051a39Sopenharmony_ci * the setters check the range 642e1051a39Sopenharmony_ci */ 643e1051a39Sopenharmony_ci if (block_size >= 0) { 644e1051a39Sopenharmony_ci if (cctx->ctx) 645e1051a39Sopenharmony_ci rv = SSL_CTX_set_block_padding(cctx->ctx, block_size); 646e1051a39Sopenharmony_ci if (cctx->ssl) 647e1051a39Sopenharmony_ci rv = SSL_set_block_padding(cctx->ssl, block_size); 648e1051a39Sopenharmony_ci } 649e1051a39Sopenharmony_ci return rv; 650e1051a39Sopenharmony_ci} 651e1051a39Sopenharmony_ci 652e1051a39Sopenharmony_ci 653e1051a39Sopenharmony_cistatic int cmd_NumTickets(SSL_CONF_CTX *cctx, const char *value) 654e1051a39Sopenharmony_ci{ 655e1051a39Sopenharmony_ci int rv = 0; 656e1051a39Sopenharmony_ci int num_tickets = atoi(value); 657e1051a39Sopenharmony_ci 658e1051a39Sopenharmony_ci if (num_tickets >= 0) { 659e1051a39Sopenharmony_ci if (cctx->ctx) 660e1051a39Sopenharmony_ci rv = SSL_CTX_set_num_tickets(cctx->ctx, num_tickets); 661e1051a39Sopenharmony_ci if (cctx->ssl) 662e1051a39Sopenharmony_ci rv = SSL_set_num_tickets(cctx->ssl, num_tickets); 663e1051a39Sopenharmony_ci } 664e1051a39Sopenharmony_ci return rv; 665e1051a39Sopenharmony_ci} 666e1051a39Sopenharmony_ci 667e1051a39Sopenharmony_citypedef struct { 668e1051a39Sopenharmony_ci int (*cmd) (SSL_CONF_CTX *cctx, const char *value); 669e1051a39Sopenharmony_ci const char *str_file; 670e1051a39Sopenharmony_ci const char *str_cmdline; 671e1051a39Sopenharmony_ci unsigned short flags; 672e1051a39Sopenharmony_ci unsigned short value_type; 673e1051a39Sopenharmony_ci} ssl_conf_cmd_tbl; 674e1051a39Sopenharmony_ci 675e1051a39Sopenharmony_ci/* Table of supported parameters */ 676e1051a39Sopenharmony_ci 677e1051a39Sopenharmony_ci#define SSL_CONF_CMD(name, cmdopt, flags, type) \ 678e1051a39Sopenharmony_ci {cmd_##name, #name, cmdopt, flags, type} 679e1051a39Sopenharmony_ci 680e1051a39Sopenharmony_ci#define SSL_CONF_CMD_STRING(name, cmdopt, flags) \ 681e1051a39Sopenharmony_ci SSL_CONF_CMD(name, cmdopt, flags, SSL_CONF_TYPE_STRING) 682e1051a39Sopenharmony_ci 683e1051a39Sopenharmony_ci#define SSL_CONF_CMD_SWITCH(name, flags) \ 684e1051a39Sopenharmony_ci {0, NULL, name, flags, SSL_CONF_TYPE_NONE} 685e1051a39Sopenharmony_ci 686e1051a39Sopenharmony_ci/* See apps/include/opt.h if you change this table. */ 687e1051a39Sopenharmony_ci/* The SSL_CONF_CMD_SWITCH should be the same order as ssl_cmd_switches */ 688e1051a39Sopenharmony_cistatic const ssl_conf_cmd_tbl ssl_conf_cmds[] = { 689e1051a39Sopenharmony_ci SSL_CONF_CMD_SWITCH("no_ssl3", 0), 690e1051a39Sopenharmony_ci SSL_CONF_CMD_SWITCH("no_tls1", 0), 691e1051a39Sopenharmony_ci SSL_CONF_CMD_SWITCH("no_tls1_1", 0), 692e1051a39Sopenharmony_ci SSL_CONF_CMD_SWITCH("no_tls1_2", 0), 693e1051a39Sopenharmony_ci SSL_CONF_CMD_SWITCH("no_tls1_3", 0), 694e1051a39Sopenharmony_ci SSL_CONF_CMD_SWITCH("bugs", 0), 695e1051a39Sopenharmony_ci SSL_CONF_CMD_SWITCH("no_comp", 0), 696e1051a39Sopenharmony_ci SSL_CONF_CMD_SWITCH("comp", 0), 697e1051a39Sopenharmony_ci SSL_CONF_CMD_SWITCH("ecdh_single", SSL_CONF_FLAG_SERVER), 698e1051a39Sopenharmony_ci SSL_CONF_CMD_SWITCH("no_ticket", 0), 699e1051a39Sopenharmony_ci SSL_CONF_CMD_SWITCH("serverpref", SSL_CONF_FLAG_SERVER), 700e1051a39Sopenharmony_ci SSL_CONF_CMD_SWITCH("legacy_renegotiation", 0), 701e1051a39Sopenharmony_ci SSL_CONF_CMD_SWITCH("client_renegotiation", SSL_CONF_FLAG_SERVER), 702e1051a39Sopenharmony_ci SSL_CONF_CMD_SWITCH("legacy_server_connect", SSL_CONF_FLAG_CLIENT), 703e1051a39Sopenharmony_ci SSL_CONF_CMD_SWITCH("no_renegotiation", 0), 704e1051a39Sopenharmony_ci SSL_CONF_CMD_SWITCH("no_resumption_on_reneg", SSL_CONF_FLAG_SERVER), 705e1051a39Sopenharmony_ci SSL_CONF_CMD_SWITCH("no_legacy_server_connect", SSL_CONF_FLAG_CLIENT), 706e1051a39Sopenharmony_ci SSL_CONF_CMD_SWITCH("allow_no_dhe_kex", 0), 707e1051a39Sopenharmony_ci SSL_CONF_CMD_SWITCH("prioritize_chacha", SSL_CONF_FLAG_SERVER), 708e1051a39Sopenharmony_ci SSL_CONF_CMD_SWITCH("strict", 0), 709e1051a39Sopenharmony_ci SSL_CONF_CMD_SWITCH("no_middlebox", 0), 710e1051a39Sopenharmony_ci SSL_CONF_CMD_SWITCH("anti_replay", SSL_CONF_FLAG_SERVER), 711e1051a39Sopenharmony_ci SSL_CONF_CMD_SWITCH("no_anti_replay", SSL_CONF_FLAG_SERVER), 712e1051a39Sopenharmony_ci SSL_CONF_CMD_SWITCH("no_etm", 0), 713e1051a39Sopenharmony_ci SSL_CONF_CMD_STRING(SignatureAlgorithms, "sigalgs", 0), 714e1051a39Sopenharmony_ci SSL_CONF_CMD_STRING(ClientSignatureAlgorithms, "client_sigalgs", 0), 715e1051a39Sopenharmony_ci SSL_CONF_CMD_STRING(Curves, "curves", 0), 716e1051a39Sopenharmony_ci SSL_CONF_CMD_STRING(Groups, "groups", 0), 717e1051a39Sopenharmony_ci SSL_CONF_CMD_STRING(ECDHParameters, "named_curve", SSL_CONF_FLAG_SERVER), 718e1051a39Sopenharmony_ci SSL_CONF_CMD_STRING(CipherString, "cipher", 0), 719e1051a39Sopenharmony_ci SSL_CONF_CMD_STRING(Ciphersuites, "ciphersuites", 0), 720e1051a39Sopenharmony_ci SSL_CONF_CMD_STRING(Protocol, NULL, 0), 721e1051a39Sopenharmony_ci SSL_CONF_CMD_STRING(MinProtocol, "min_protocol", 0), 722e1051a39Sopenharmony_ci SSL_CONF_CMD_STRING(MaxProtocol, "max_protocol", 0), 723e1051a39Sopenharmony_ci SSL_CONF_CMD_STRING(Options, NULL, 0), 724e1051a39Sopenharmony_ci SSL_CONF_CMD_STRING(VerifyMode, NULL, 0), 725e1051a39Sopenharmony_ci SSL_CONF_CMD(Certificate, "cert", SSL_CONF_FLAG_CERTIFICATE, 726e1051a39Sopenharmony_ci SSL_CONF_TYPE_FILE), 727e1051a39Sopenharmony_ci SSL_CONF_CMD(PrivateKey, "key", SSL_CONF_FLAG_CERTIFICATE, 728e1051a39Sopenharmony_ci SSL_CONF_TYPE_FILE), 729e1051a39Sopenharmony_ci SSL_CONF_CMD(ServerInfoFile, NULL, 730e1051a39Sopenharmony_ci SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CERTIFICATE, 731e1051a39Sopenharmony_ci SSL_CONF_TYPE_FILE), 732e1051a39Sopenharmony_ci SSL_CONF_CMD(ChainCAPath, "chainCApath", SSL_CONF_FLAG_CERTIFICATE, 733e1051a39Sopenharmony_ci SSL_CONF_TYPE_DIR), 734e1051a39Sopenharmony_ci SSL_CONF_CMD(ChainCAFile, "chainCAfile", SSL_CONF_FLAG_CERTIFICATE, 735e1051a39Sopenharmony_ci SSL_CONF_TYPE_FILE), 736e1051a39Sopenharmony_ci SSL_CONF_CMD(ChainCAStore, "chainCAstore", SSL_CONF_FLAG_CERTIFICATE, 737e1051a39Sopenharmony_ci SSL_CONF_TYPE_STORE), 738e1051a39Sopenharmony_ci SSL_CONF_CMD(VerifyCAPath, "verifyCApath", SSL_CONF_FLAG_CERTIFICATE, 739e1051a39Sopenharmony_ci SSL_CONF_TYPE_DIR), 740e1051a39Sopenharmony_ci SSL_CONF_CMD(VerifyCAFile, "verifyCAfile", SSL_CONF_FLAG_CERTIFICATE, 741e1051a39Sopenharmony_ci SSL_CONF_TYPE_FILE), 742e1051a39Sopenharmony_ci SSL_CONF_CMD(VerifyCAStore, "verifyCAstore", SSL_CONF_FLAG_CERTIFICATE, 743e1051a39Sopenharmony_ci SSL_CONF_TYPE_STORE), 744e1051a39Sopenharmony_ci SSL_CONF_CMD(RequestCAFile, "requestCAFile", SSL_CONF_FLAG_CERTIFICATE, 745e1051a39Sopenharmony_ci SSL_CONF_TYPE_FILE), 746e1051a39Sopenharmony_ci SSL_CONF_CMD(ClientCAFile, NULL, 747e1051a39Sopenharmony_ci SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CERTIFICATE, 748e1051a39Sopenharmony_ci SSL_CONF_TYPE_FILE), 749e1051a39Sopenharmony_ci SSL_CONF_CMD(RequestCAPath, NULL, SSL_CONF_FLAG_CERTIFICATE, 750e1051a39Sopenharmony_ci SSL_CONF_TYPE_DIR), 751e1051a39Sopenharmony_ci SSL_CONF_CMD(ClientCAPath, NULL, 752e1051a39Sopenharmony_ci SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CERTIFICATE, 753e1051a39Sopenharmony_ci SSL_CONF_TYPE_DIR), 754e1051a39Sopenharmony_ci SSL_CONF_CMD(RequestCAStore, "requestCAStore", SSL_CONF_FLAG_CERTIFICATE, 755e1051a39Sopenharmony_ci SSL_CONF_TYPE_STORE), 756e1051a39Sopenharmony_ci SSL_CONF_CMD(ClientCAStore, NULL, 757e1051a39Sopenharmony_ci SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CERTIFICATE, 758e1051a39Sopenharmony_ci SSL_CONF_TYPE_STORE), 759e1051a39Sopenharmony_ci SSL_CONF_CMD(DHParameters, "dhparam", 760e1051a39Sopenharmony_ci SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CERTIFICATE, 761e1051a39Sopenharmony_ci SSL_CONF_TYPE_FILE), 762e1051a39Sopenharmony_ci SSL_CONF_CMD_STRING(RecordPadding, "record_padding", 0), 763e1051a39Sopenharmony_ci SSL_CONF_CMD_STRING(NumTickets, "num_tickets", SSL_CONF_FLAG_SERVER), 764e1051a39Sopenharmony_ci}; 765e1051a39Sopenharmony_ci 766e1051a39Sopenharmony_ci/* Supported switches: must match order of switches in ssl_conf_cmds */ 767e1051a39Sopenharmony_cistatic const ssl_switch_tbl ssl_cmd_switches[] = { 768e1051a39Sopenharmony_ci {SSL_OP_NO_SSLv3, 0}, /* no_ssl3 */ 769e1051a39Sopenharmony_ci {SSL_OP_NO_TLSv1, 0}, /* no_tls1 */ 770e1051a39Sopenharmony_ci {SSL_OP_NO_TLSv1_1, 0}, /* no_tls1_1 */ 771e1051a39Sopenharmony_ci {SSL_OP_NO_TLSv1_2, 0}, /* no_tls1_2 */ 772e1051a39Sopenharmony_ci {SSL_OP_NO_TLSv1_3, 0}, /* no_tls1_3 */ 773e1051a39Sopenharmony_ci {SSL_OP_ALL, 0}, /* bugs */ 774e1051a39Sopenharmony_ci {SSL_OP_NO_COMPRESSION, 0}, /* no_comp */ 775e1051a39Sopenharmony_ci {SSL_OP_NO_COMPRESSION, SSL_TFLAG_INV}, /* comp */ 776e1051a39Sopenharmony_ci {SSL_OP_SINGLE_ECDH_USE, 0}, /* ecdh_single */ 777e1051a39Sopenharmony_ci {SSL_OP_NO_TICKET, 0}, /* no_ticket */ 778e1051a39Sopenharmony_ci {SSL_OP_CIPHER_SERVER_PREFERENCE, 0}, /* serverpref */ 779e1051a39Sopenharmony_ci /* legacy_renegotiation */ 780e1051a39Sopenharmony_ci {SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION, 0}, 781e1051a39Sopenharmony_ci /* Allow client renegotiation */ 782e1051a39Sopenharmony_ci {SSL_OP_ALLOW_CLIENT_RENEGOTIATION, 0}, 783e1051a39Sopenharmony_ci /* legacy_server_connect */ 784e1051a39Sopenharmony_ci {SSL_OP_LEGACY_SERVER_CONNECT, 0}, 785e1051a39Sopenharmony_ci /* no_renegotiation */ 786e1051a39Sopenharmony_ci {SSL_OP_NO_RENEGOTIATION, 0}, 787e1051a39Sopenharmony_ci /* no_resumption_on_reneg */ 788e1051a39Sopenharmony_ci {SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION, 0}, 789e1051a39Sopenharmony_ci /* no_legacy_server_connect */ 790e1051a39Sopenharmony_ci {SSL_OP_LEGACY_SERVER_CONNECT, SSL_TFLAG_INV}, 791e1051a39Sopenharmony_ci /* allow_no_dhe_kex */ 792e1051a39Sopenharmony_ci {SSL_OP_ALLOW_NO_DHE_KEX, 0}, 793e1051a39Sopenharmony_ci /* chacha reprioritization */ 794e1051a39Sopenharmony_ci {SSL_OP_PRIORITIZE_CHACHA, 0}, 795e1051a39Sopenharmony_ci {SSL_CERT_FLAG_TLS_STRICT, SSL_TFLAG_CERT}, /* strict */ 796e1051a39Sopenharmony_ci /* no_middlebox */ 797e1051a39Sopenharmony_ci {SSL_OP_ENABLE_MIDDLEBOX_COMPAT, SSL_TFLAG_INV}, 798e1051a39Sopenharmony_ci /* anti_replay */ 799e1051a39Sopenharmony_ci {SSL_OP_NO_ANTI_REPLAY, SSL_TFLAG_INV}, 800e1051a39Sopenharmony_ci /* no_anti_replay */ 801e1051a39Sopenharmony_ci {SSL_OP_NO_ANTI_REPLAY, 0}, 802e1051a39Sopenharmony_ci /* no Encrypt-then-Mac */ 803e1051a39Sopenharmony_ci {SSL_OP_NO_ENCRYPT_THEN_MAC, 0}, 804e1051a39Sopenharmony_ci}; 805e1051a39Sopenharmony_ci 806e1051a39Sopenharmony_cistatic int ssl_conf_cmd_skip_prefix(SSL_CONF_CTX *cctx, const char **pcmd) 807e1051a39Sopenharmony_ci{ 808e1051a39Sopenharmony_ci if (pcmd == NULL || *pcmd == NULL) 809e1051a39Sopenharmony_ci return 0; 810e1051a39Sopenharmony_ci /* If a prefix is set, check and skip */ 811e1051a39Sopenharmony_ci if (cctx->prefix) { 812e1051a39Sopenharmony_ci if (strlen(*pcmd) <= cctx->prefixlen) 813e1051a39Sopenharmony_ci return 0; 814e1051a39Sopenharmony_ci if (cctx->flags & SSL_CONF_FLAG_CMDLINE && 815e1051a39Sopenharmony_ci strncmp(*pcmd, cctx->prefix, cctx->prefixlen)) 816e1051a39Sopenharmony_ci return 0; 817e1051a39Sopenharmony_ci if (cctx->flags & SSL_CONF_FLAG_FILE && 818e1051a39Sopenharmony_ci OPENSSL_strncasecmp(*pcmd, cctx->prefix, cctx->prefixlen)) 819e1051a39Sopenharmony_ci return 0; 820e1051a39Sopenharmony_ci *pcmd += cctx->prefixlen; 821e1051a39Sopenharmony_ci } else if (cctx->flags & SSL_CONF_FLAG_CMDLINE) { 822e1051a39Sopenharmony_ci if (**pcmd != '-' || !(*pcmd)[1]) 823e1051a39Sopenharmony_ci return 0; 824e1051a39Sopenharmony_ci *pcmd += 1; 825e1051a39Sopenharmony_ci } 826e1051a39Sopenharmony_ci return 1; 827e1051a39Sopenharmony_ci} 828e1051a39Sopenharmony_ci 829e1051a39Sopenharmony_ci/* Determine if a command is allowed according to cctx flags */ 830e1051a39Sopenharmony_cistatic int ssl_conf_cmd_allowed(SSL_CONF_CTX *cctx, const ssl_conf_cmd_tbl * t) 831e1051a39Sopenharmony_ci{ 832e1051a39Sopenharmony_ci unsigned int tfl = t->flags; 833e1051a39Sopenharmony_ci unsigned int cfl = cctx->flags; 834e1051a39Sopenharmony_ci if ((tfl & SSL_CONF_FLAG_SERVER) && !(cfl & SSL_CONF_FLAG_SERVER)) 835e1051a39Sopenharmony_ci return 0; 836e1051a39Sopenharmony_ci if ((tfl & SSL_CONF_FLAG_CLIENT) && !(cfl & SSL_CONF_FLAG_CLIENT)) 837e1051a39Sopenharmony_ci return 0; 838e1051a39Sopenharmony_ci if ((tfl & SSL_CONF_FLAG_CERTIFICATE) 839e1051a39Sopenharmony_ci && !(cfl & SSL_CONF_FLAG_CERTIFICATE)) 840e1051a39Sopenharmony_ci return 0; 841e1051a39Sopenharmony_ci return 1; 842e1051a39Sopenharmony_ci} 843e1051a39Sopenharmony_ci 844e1051a39Sopenharmony_cistatic const ssl_conf_cmd_tbl *ssl_conf_cmd_lookup(SSL_CONF_CTX *cctx, 845e1051a39Sopenharmony_ci const char *cmd) 846e1051a39Sopenharmony_ci{ 847e1051a39Sopenharmony_ci const ssl_conf_cmd_tbl *t; 848e1051a39Sopenharmony_ci size_t i; 849e1051a39Sopenharmony_ci if (cmd == NULL) 850e1051a39Sopenharmony_ci return NULL; 851e1051a39Sopenharmony_ci 852e1051a39Sopenharmony_ci /* Look for matching parameter name in table */ 853e1051a39Sopenharmony_ci for (i = 0, t = ssl_conf_cmds; i < OSSL_NELEM(ssl_conf_cmds); i++, t++) { 854e1051a39Sopenharmony_ci if (ssl_conf_cmd_allowed(cctx, t)) { 855e1051a39Sopenharmony_ci if (cctx->flags & SSL_CONF_FLAG_CMDLINE) { 856e1051a39Sopenharmony_ci if (t->str_cmdline && strcmp(t->str_cmdline, cmd) == 0) 857e1051a39Sopenharmony_ci return t; 858e1051a39Sopenharmony_ci } 859e1051a39Sopenharmony_ci if (cctx->flags & SSL_CONF_FLAG_FILE) { 860e1051a39Sopenharmony_ci if (t->str_file && OPENSSL_strcasecmp(t->str_file, cmd) == 0) 861e1051a39Sopenharmony_ci return t; 862e1051a39Sopenharmony_ci } 863e1051a39Sopenharmony_ci } 864e1051a39Sopenharmony_ci } 865e1051a39Sopenharmony_ci return NULL; 866e1051a39Sopenharmony_ci} 867e1051a39Sopenharmony_ci 868e1051a39Sopenharmony_cistatic int ctrl_switch_option(SSL_CONF_CTX *cctx, const ssl_conf_cmd_tbl * cmd) 869e1051a39Sopenharmony_ci{ 870e1051a39Sopenharmony_ci /* Find index of command in table */ 871e1051a39Sopenharmony_ci size_t idx = cmd - ssl_conf_cmds; 872e1051a39Sopenharmony_ci const ssl_switch_tbl *scmd; 873e1051a39Sopenharmony_ci /* Sanity check index */ 874e1051a39Sopenharmony_ci if (idx >= OSSL_NELEM(ssl_cmd_switches)) 875e1051a39Sopenharmony_ci return 0; 876e1051a39Sopenharmony_ci /* Obtain switches entry with same index */ 877e1051a39Sopenharmony_ci scmd = ssl_cmd_switches + idx; 878e1051a39Sopenharmony_ci ssl_set_option(cctx, scmd->name_flags, scmd->option_value, 1); 879e1051a39Sopenharmony_ci return 1; 880e1051a39Sopenharmony_ci} 881e1051a39Sopenharmony_ci 882e1051a39Sopenharmony_ciint SSL_CONF_cmd(SSL_CONF_CTX *cctx, const char *cmd, const char *value) 883e1051a39Sopenharmony_ci{ 884e1051a39Sopenharmony_ci const ssl_conf_cmd_tbl *runcmd; 885e1051a39Sopenharmony_ci if (cmd == NULL) { 886e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_SSL, SSL_R_INVALID_NULL_CMD_NAME); 887e1051a39Sopenharmony_ci return 0; 888e1051a39Sopenharmony_ci } 889e1051a39Sopenharmony_ci 890e1051a39Sopenharmony_ci if (!ssl_conf_cmd_skip_prefix(cctx, &cmd)) 891e1051a39Sopenharmony_ci return -2; 892e1051a39Sopenharmony_ci 893e1051a39Sopenharmony_ci runcmd = ssl_conf_cmd_lookup(cctx, cmd); 894e1051a39Sopenharmony_ci 895e1051a39Sopenharmony_ci if (runcmd) { 896e1051a39Sopenharmony_ci int rv; 897e1051a39Sopenharmony_ci if (runcmd->value_type == SSL_CONF_TYPE_NONE) { 898e1051a39Sopenharmony_ci return ctrl_switch_option(cctx, runcmd); 899e1051a39Sopenharmony_ci } 900e1051a39Sopenharmony_ci if (value == NULL) 901e1051a39Sopenharmony_ci return -3; 902e1051a39Sopenharmony_ci rv = runcmd->cmd(cctx, value); 903e1051a39Sopenharmony_ci if (rv > 0) 904e1051a39Sopenharmony_ci return 2; 905e1051a39Sopenharmony_ci if (rv == -2) 906e1051a39Sopenharmony_ci return -2; 907e1051a39Sopenharmony_ci if (cctx->flags & SSL_CONF_FLAG_SHOW_ERRORS) 908e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_SSL, SSL_R_BAD_VALUE, 909e1051a39Sopenharmony_ci "cmd=%s, value=%s", cmd, value); 910e1051a39Sopenharmony_ci return 0; 911e1051a39Sopenharmony_ci } 912e1051a39Sopenharmony_ci 913e1051a39Sopenharmony_ci if (cctx->flags & SSL_CONF_FLAG_SHOW_ERRORS) 914e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_SSL, SSL_R_UNKNOWN_CMD_NAME, "cmd=%s", cmd); 915e1051a39Sopenharmony_ci 916e1051a39Sopenharmony_ci return -2; 917e1051a39Sopenharmony_ci} 918e1051a39Sopenharmony_ci 919e1051a39Sopenharmony_ciint SSL_CONF_cmd_argv(SSL_CONF_CTX *cctx, int *pargc, char ***pargv) 920e1051a39Sopenharmony_ci{ 921e1051a39Sopenharmony_ci int rv; 922e1051a39Sopenharmony_ci const char *arg = NULL, *argn; 923e1051a39Sopenharmony_ci 924e1051a39Sopenharmony_ci if (pargc != NULL && *pargc == 0) 925e1051a39Sopenharmony_ci return 0; 926e1051a39Sopenharmony_ci if (pargc == NULL || *pargc > 0) 927e1051a39Sopenharmony_ci arg = **pargv; 928e1051a39Sopenharmony_ci if (arg == NULL) 929e1051a39Sopenharmony_ci return 0; 930e1051a39Sopenharmony_ci if (pargc == NULL || *pargc > 1) 931e1051a39Sopenharmony_ci argn = (*pargv)[1]; 932e1051a39Sopenharmony_ci else 933e1051a39Sopenharmony_ci argn = NULL; 934e1051a39Sopenharmony_ci cctx->flags &= ~SSL_CONF_FLAG_FILE; 935e1051a39Sopenharmony_ci cctx->flags |= SSL_CONF_FLAG_CMDLINE; 936e1051a39Sopenharmony_ci rv = SSL_CONF_cmd(cctx, arg, argn); 937e1051a39Sopenharmony_ci if (rv > 0) { 938e1051a39Sopenharmony_ci /* Success: update pargc, pargv */ 939e1051a39Sopenharmony_ci (*pargv) += rv; 940e1051a39Sopenharmony_ci if (pargc) 941e1051a39Sopenharmony_ci (*pargc) -= rv; 942e1051a39Sopenharmony_ci return rv; 943e1051a39Sopenharmony_ci } 944e1051a39Sopenharmony_ci /* Unknown switch: indicate no arguments processed */ 945e1051a39Sopenharmony_ci if (rv == -2) 946e1051a39Sopenharmony_ci return 0; 947e1051a39Sopenharmony_ci /* Some error occurred processing command, return fatal error */ 948e1051a39Sopenharmony_ci if (rv == 0) 949e1051a39Sopenharmony_ci return -1; 950e1051a39Sopenharmony_ci return rv; 951e1051a39Sopenharmony_ci} 952e1051a39Sopenharmony_ci 953e1051a39Sopenharmony_ciint SSL_CONF_cmd_value_type(SSL_CONF_CTX *cctx, const char *cmd) 954e1051a39Sopenharmony_ci{ 955e1051a39Sopenharmony_ci if (ssl_conf_cmd_skip_prefix(cctx, &cmd)) { 956e1051a39Sopenharmony_ci const ssl_conf_cmd_tbl *runcmd; 957e1051a39Sopenharmony_ci runcmd = ssl_conf_cmd_lookup(cctx, cmd); 958e1051a39Sopenharmony_ci if (runcmd) 959e1051a39Sopenharmony_ci return runcmd->value_type; 960e1051a39Sopenharmony_ci } 961e1051a39Sopenharmony_ci return SSL_CONF_TYPE_UNKNOWN; 962e1051a39Sopenharmony_ci} 963e1051a39Sopenharmony_ci 964e1051a39Sopenharmony_ciSSL_CONF_CTX *SSL_CONF_CTX_new(void) 965e1051a39Sopenharmony_ci{ 966e1051a39Sopenharmony_ci SSL_CONF_CTX *ret = OPENSSL_zalloc(sizeof(*ret)); 967e1051a39Sopenharmony_ci 968e1051a39Sopenharmony_ci return ret; 969e1051a39Sopenharmony_ci} 970e1051a39Sopenharmony_ci 971e1051a39Sopenharmony_ciint SSL_CONF_CTX_finish(SSL_CONF_CTX *cctx) 972e1051a39Sopenharmony_ci{ 973e1051a39Sopenharmony_ci /* See if any certificates are missing private keys */ 974e1051a39Sopenharmony_ci size_t i; 975e1051a39Sopenharmony_ci CERT *c = NULL; 976e1051a39Sopenharmony_ci if (cctx->ctx) 977e1051a39Sopenharmony_ci c = cctx->ctx->cert; 978e1051a39Sopenharmony_ci else if (cctx->ssl) 979e1051a39Sopenharmony_ci c = cctx->ssl->cert; 980e1051a39Sopenharmony_ci if (c && cctx->flags & SSL_CONF_FLAG_REQUIRE_PRIVATE) { 981e1051a39Sopenharmony_ci for (i = 0; i < SSL_PKEY_NUM; i++) { 982e1051a39Sopenharmony_ci const char *p = cctx->cert_filename[i]; 983e1051a39Sopenharmony_ci /* 984e1051a39Sopenharmony_ci * If missing private key try to load one from certificate file 985e1051a39Sopenharmony_ci */ 986e1051a39Sopenharmony_ci if (p && !c->pkeys[i].privatekey) { 987e1051a39Sopenharmony_ci if (!cmd_PrivateKey(cctx, p)) 988e1051a39Sopenharmony_ci return 0; 989e1051a39Sopenharmony_ci } 990e1051a39Sopenharmony_ci } 991e1051a39Sopenharmony_ci } 992e1051a39Sopenharmony_ci if (cctx->canames) { 993e1051a39Sopenharmony_ci if (cctx->ssl) 994e1051a39Sopenharmony_ci SSL_set0_CA_list(cctx->ssl, cctx->canames); 995e1051a39Sopenharmony_ci else if (cctx->ctx) 996e1051a39Sopenharmony_ci SSL_CTX_set0_CA_list(cctx->ctx, cctx->canames); 997e1051a39Sopenharmony_ci else 998e1051a39Sopenharmony_ci sk_X509_NAME_pop_free(cctx->canames, X509_NAME_free); 999e1051a39Sopenharmony_ci cctx->canames = NULL; 1000e1051a39Sopenharmony_ci } 1001e1051a39Sopenharmony_ci return 1; 1002e1051a39Sopenharmony_ci} 1003e1051a39Sopenharmony_ci 1004e1051a39Sopenharmony_civoid SSL_CONF_CTX_free(SSL_CONF_CTX *cctx) 1005e1051a39Sopenharmony_ci{ 1006e1051a39Sopenharmony_ci if (cctx) { 1007e1051a39Sopenharmony_ci size_t i; 1008e1051a39Sopenharmony_ci for (i = 0; i < SSL_PKEY_NUM; i++) 1009e1051a39Sopenharmony_ci OPENSSL_free(cctx->cert_filename[i]); 1010e1051a39Sopenharmony_ci OPENSSL_free(cctx->prefix); 1011e1051a39Sopenharmony_ci sk_X509_NAME_pop_free(cctx->canames, X509_NAME_free); 1012e1051a39Sopenharmony_ci OPENSSL_free(cctx); 1013e1051a39Sopenharmony_ci } 1014e1051a39Sopenharmony_ci} 1015e1051a39Sopenharmony_ci 1016e1051a39Sopenharmony_ciunsigned int SSL_CONF_CTX_set_flags(SSL_CONF_CTX *cctx, unsigned int flags) 1017e1051a39Sopenharmony_ci{ 1018e1051a39Sopenharmony_ci cctx->flags |= flags; 1019e1051a39Sopenharmony_ci return cctx->flags; 1020e1051a39Sopenharmony_ci} 1021e1051a39Sopenharmony_ci 1022e1051a39Sopenharmony_ciunsigned int SSL_CONF_CTX_clear_flags(SSL_CONF_CTX *cctx, unsigned int flags) 1023e1051a39Sopenharmony_ci{ 1024e1051a39Sopenharmony_ci cctx->flags &= ~flags; 1025e1051a39Sopenharmony_ci return cctx->flags; 1026e1051a39Sopenharmony_ci} 1027e1051a39Sopenharmony_ci 1028e1051a39Sopenharmony_ciint SSL_CONF_CTX_set1_prefix(SSL_CONF_CTX *cctx, const char *pre) 1029e1051a39Sopenharmony_ci{ 1030e1051a39Sopenharmony_ci char *tmp = NULL; 1031e1051a39Sopenharmony_ci if (pre) { 1032e1051a39Sopenharmony_ci tmp = OPENSSL_strdup(pre); 1033e1051a39Sopenharmony_ci if (tmp == NULL) 1034e1051a39Sopenharmony_ci return 0; 1035e1051a39Sopenharmony_ci } 1036e1051a39Sopenharmony_ci OPENSSL_free(cctx->prefix); 1037e1051a39Sopenharmony_ci cctx->prefix = tmp; 1038e1051a39Sopenharmony_ci if (tmp) 1039e1051a39Sopenharmony_ci cctx->prefixlen = strlen(tmp); 1040e1051a39Sopenharmony_ci else 1041e1051a39Sopenharmony_ci cctx->prefixlen = 0; 1042e1051a39Sopenharmony_ci return 1; 1043e1051a39Sopenharmony_ci} 1044e1051a39Sopenharmony_ci 1045e1051a39Sopenharmony_civoid SSL_CONF_CTX_set_ssl(SSL_CONF_CTX *cctx, SSL *ssl) 1046e1051a39Sopenharmony_ci{ 1047e1051a39Sopenharmony_ci cctx->ssl = ssl; 1048e1051a39Sopenharmony_ci cctx->ctx = NULL; 1049e1051a39Sopenharmony_ci if (ssl) { 1050e1051a39Sopenharmony_ci cctx->poptions = &ssl->options; 1051e1051a39Sopenharmony_ci cctx->min_version = &ssl->min_proto_version; 1052e1051a39Sopenharmony_ci cctx->max_version = &ssl->max_proto_version; 1053e1051a39Sopenharmony_ci cctx->pcert_flags = &ssl->cert->cert_flags; 1054e1051a39Sopenharmony_ci cctx->pvfy_flags = &ssl->verify_mode; 1055e1051a39Sopenharmony_ci } else { 1056e1051a39Sopenharmony_ci cctx->poptions = NULL; 1057e1051a39Sopenharmony_ci cctx->min_version = NULL; 1058e1051a39Sopenharmony_ci cctx->max_version = NULL; 1059e1051a39Sopenharmony_ci cctx->pcert_flags = NULL; 1060e1051a39Sopenharmony_ci cctx->pvfy_flags = NULL; 1061e1051a39Sopenharmony_ci } 1062e1051a39Sopenharmony_ci} 1063e1051a39Sopenharmony_ci 1064e1051a39Sopenharmony_civoid SSL_CONF_CTX_set_ssl_ctx(SSL_CONF_CTX *cctx, SSL_CTX *ctx) 1065e1051a39Sopenharmony_ci{ 1066e1051a39Sopenharmony_ci cctx->ctx = ctx; 1067e1051a39Sopenharmony_ci cctx->ssl = NULL; 1068e1051a39Sopenharmony_ci if (ctx) { 1069e1051a39Sopenharmony_ci cctx->poptions = &ctx->options; 1070e1051a39Sopenharmony_ci cctx->min_version = &ctx->min_proto_version; 1071e1051a39Sopenharmony_ci cctx->max_version = &ctx->max_proto_version; 1072e1051a39Sopenharmony_ci cctx->pcert_flags = &ctx->cert->cert_flags; 1073e1051a39Sopenharmony_ci cctx->pvfy_flags = &ctx->verify_mode; 1074e1051a39Sopenharmony_ci } else { 1075e1051a39Sopenharmony_ci cctx->poptions = NULL; 1076e1051a39Sopenharmony_ci cctx->min_version = NULL; 1077e1051a39Sopenharmony_ci cctx->max_version = NULL; 1078e1051a39Sopenharmony_ci cctx->pcert_flags = NULL; 1079e1051a39Sopenharmony_ci cctx->pvfy_flags = NULL; 1080e1051a39Sopenharmony_ci } 1081e1051a39Sopenharmony_ci} 1082