1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2004-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 12e1051a39Sopenharmony_ci#include "internal/cryptlib.h" 13e1051a39Sopenharmony_ci#include <openssl/crypto.h> 14e1051a39Sopenharmony_ci#include <openssl/buffer.h> 15e1051a39Sopenharmony_ci#include <openssl/x509.h> 16e1051a39Sopenharmony_ci#include <openssl/x509v3.h> 17e1051a39Sopenharmony_ci#include "crypto/x509.h" 18e1051a39Sopenharmony_ci 19e1051a39Sopenharmony_ci#include "x509_local.h" 20e1051a39Sopenharmony_ci 21e1051a39Sopenharmony_ci/* X509_VERIFY_PARAM functions */ 22e1051a39Sopenharmony_ci 23e1051a39Sopenharmony_ci#define SET_HOST 0 24e1051a39Sopenharmony_ci#define ADD_HOST 1 25e1051a39Sopenharmony_ci 26e1051a39Sopenharmony_cistatic char *str_copy(const char *s) 27e1051a39Sopenharmony_ci{ 28e1051a39Sopenharmony_ci return OPENSSL_strdup(s); 29e1051a39Sopenharmony_ci} 30e1051a39Sopenharmony_ci 31e1051a39Sopenharmony_cistatic void str_free(char *s) 32e1051a39Sopenharmony_ci{ 33e1051a39Sopenharmony_ci OPENSSL_free(s); 34e1051a39Sopenharmony_ci} 35e1051a39Sopenharmony_ci 36e1051a39Sopenharmony_cistatic int int_x509_param_set_hosts(X509_VERIFY_PARAM *vpm, int mode, 37e1051a39Sopenharmony_ci const char *name, size_t namelen) 38e1051a39Sopenharmony_ci{ 39e1051a39Sopenharmony_ci char *copy; 40e1051a39Sopenharmony_ci 41e1051a39Sopenharmony_ci /* 42e1051a39Sopenharmony_ci * Refuse names with embedded NUL bytes, except perhaps as final byte. 43e1051a39Sopenharmony_ci * XXX: Do we need to push an error onto the error stack? 44e1051a39Sopenharmony_ci */ 45e1051a39Sopenharmony_ci if (namelen == 0 || name == NULL) 46e1051a39Sopenharmony_ci namelen = name ? strlen(name) : 0; 47e1051a39Sopenharmony_ci else if (name != NULL 48e1051a39Sopenharmony_ci && memchr(name, '\0', namelen > 1 ? namelen - 1 : namelen) != NULL) 49e1051a39Sopenharmony_ci return 0; 50e1051a39Sopenharmony_ci if (namelen > 0 && name[namelen - 1] == '\0') 51e1051a39Sopenharmony_ci --namelen; 52e1051a39Sopenharmony_ci 53e1051a39Sopenharmony_ci if (mode == SET_HOST) { 54e1051a39Sopenharmony_ci sk_OPENSSL_STRING_pop_free(vpm->hosts, str_free); 55e1051a39Sopenharmony_ci vpm->hosts = NULL; 56e1051a39Sopenharmony_ci } 57e1051a39Sopenharmony_ci if (name == NULL || namelen == 0) 58e1051a39Sopenharmony_ci return 1; 59e1051a39Sopenharmony_ci 60e1051a39Sopenharmony_ci copy = OPENSSL_strndup(name, namelen); 61e1051a39Sopenharmony_ci if (copy == NULL) 62e1051a39Sopenharmony_ci return 0; 63e1051a39Sopenharmony_ci 64e1051a39Sopenharmony_ci if (vpm->hosts == NULL && 65e1051a39Sopenharmony_ci (vpm->hosts = sk_OPENSSL_STRING_new_null()) == NULL) { 66e1051a39Sopenharmony_ci OPENSSL_free(copy); 67e1051a39Sopenharmony_ci return 0; 68e1051a39Sopenharmony_ci } 69e1051a39Sopenharmony_ci 70e1051a39Sopenharmony_ci if (!sk_OPENSSL_STRING_push(vpm->hosts, copy)) { 71e1051a39Sopenharmony_ci OPENSSL_free(copy); 72e1051a39Sopenharmony_ci if (sk_OPENSSL_STRING_num(vpm->hosts) == 0) { 73e1051a39Sopenharmony_ci sk_OPENSSL_STRING_free(vpm->hosts); 74e1051a39Sopenharmony_ci vpm->hosts = NULL; 75e1051a39Sopenharmony_ci } 76e1051a39Sopenharmony_ci return 0; 77e1051a39Sopenharmony_ci } 78e1051a39Sopenharmony_ci 79e1051a39Sopenharmony_ci return 1; 80e1051a39Sopenharmony_ci} 81e1051a39Sopenharmony_ci 82e1051a39Sopenharmony_ciX509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void) 83e1051a39Sopenharmony_ci{ 84e1051a39Sopenharmony_ci X509_VERIFY_PARAM *param; 85e1051a39Sopenharmony_ci 86e1051a39Sopenharmony_ci param = OPENSSL_zalloc(sizeof(*param)); 87e1051a39Sopenharmony_ci if (param == NULL) { 88e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); 89e1051a39Sopenharmony_ci return NULL; 90e1051a39Sopenharmony_ci } 91e1051a39Sopenharmony_ci param->trust = X509_TRUST_DEFAULT; 92e1051a39Sopenharmony_ci /* param->inh_flags = X509_VP_FLAG_DEFAULT; */ 93e1051a39Sopenharmony_ci param->depth = -1; 94e1051a39Sopenharmony_ci param->auth_level = -1; /* -1 means unset, 0 is explicit */ 95e1051a39Sopenharmony_ci return param; 96e1051a39Sopenharmony_ci} 97e1051a39Sopenharmony_ci 98e1051a39Sopenharmony_civoid X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param) 99e1051a39Sopenharmony_ci{ 100e1051a39Sopenharmony_ci if (param == NULL) 101e1051a39Sopenharmony_ci return; 102e1051a39Sopenharmony_ci sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free); 103e1051a39Sopenharmony_ci sk_OPENSSL_STRING_pop_free(param->hosts, str_free); 104e1051a39Sopenharmony_ci OPENSSL_free(param->peername); 105e1051a39Sopenharmony_ci OPENSSL_free(param->email); 106e1051a39Sopenharmony_ci OPENSSL_free(param->ip); 107e1051a39Sopenharmony_ci OPENSSL_free(param); 108e1051a39Sopenharmony_ci} 109e1051a39Sopenharmony_ci 110e1051a39Sopenharmony_ci/*- 111e1051a39Sopenharmony_ci * This function determines how parameters are "inherited" from one structure 112e1051a39Sopenharmony_ci * to another. There are several different ways this can happen. 113e1051a39Sopenharmony_ci * 114e1051a39Sopenharmony_ci * 1. If a child structure needs to have its values initialized from a parent 115e1051a39Sopenharmony_ci * they are simply copied across. For example SSL_CTX copied to SSL. 116e1051a39Sopenharmony_ci * 2. If the structure should take on values only if they are currently unset. 117e1051a39Sopenharmony_ci * For example the values in an SSL structure will take appropriate value 118e1051a39Sopenharmony_ci * for SSL servers or clients but only if the application has not set new 119e1051a39Sopenharmony_ci * ones. 120e1051a39Sopenharmony_ci * 121e1051a39Sopenharmony_ci * The "inh_flags" field determines how this function behaves. 122e1051a39Sopenharmony_ci * 123e1051a39Sopenharmony_ci * Normally any values which are set in the default are not copied from the 124e1051a39Sopenharmony_ci * destination and verify flags are ORed together. 125e1051a39Sopenharmony_ci * 126e1051a39Sopenharmony_ci * If X509_VP_FLAG_DEFAULT is set then anything set in the source is copied 127e1051a39Sopenharmony_ci * to the destination. Effectively the values in "to" become default values 128e1051a39Sopenharmony_ci * which will be used only if nothing new is set in "from". 129e1051a39Sopenharmony_ci * 130e1051a39Sopenharmony_ci * If X509_VP_FLAG_OVERWRITE is set then all value are copied across whether 131e1051a39Sopenharmony_ci * they are set or not. Flags is still Ored though. 132e1051a39Sopenharmony_ci * 133e1051a39Sopenharmony_ci * If X509_VP_FLAG_RESET_FLAGS is set then the flags value is copied instead 134e1051a39Sopenharmony_ci * of ORed. 135e1051a39Sopenharmony_ci * 136e1051a39Sopenharmony_ci * If X509_VP_FLAG_LOCKED is set then no values are copied. 137e1051a39Sopenharmony_ci * 138e1051a39Sopenharmony_ci * If X509_VP_FLAG_ONCE is set then the current inh_flags setting is zeroed 139e1051a39Sopenharmony_ci * after the next call. 140e1051a39Sopenharmony_ci */ 141e1051a39Sopenharmony_ci 142e1051a39Sopenharmony_ci/* Macro to test if a field should be copied from src to dest */ 143e1051a39Sopenharmony_ci 144e1051a39Sopenharmony_ci#define test_x509_verify_param_copy(field, def) \ 145e1051a39Sopenharmony_ci (to_overwrite || (src->field != def && (to_default || dest->field == def))) 146e1051a39Sopenharmony_ci 147e1051a39Sopenharmony_ci/* Macro to test and copy a field if necessary */ 148e1051a39Sopenharmony_ci 149e1051a39Sopenharmony_ci#define x509_verify_param_copy(field, def) \ 150e1051a39Sopenharmony_ci if (test_x509_verify_param_copy(field, def)) \ 151e1051a39Sopenharmony_ci dest->field = src->field; 152e1051a39Sopenharmony_ci 153e1051a39Sopenharmony_ciint X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest, 154e1051a39Sopenharmony_ci const X509_VERIFY_PARAM *src) 155e1051a39Sopenharmony_ci{ 156e1051a39Sopenharmony_ci unsigned long inh_flags; 157e1051a39Sopenharmony_ci int to_default, to_overwrite; 158e1051a39Sopenharmony_ci 159e1051a39Sopenharmony_ci if (src == NULL) 160e1051a39Sopenharmony_ci return 1; 161e1051a39Sopenharmony_ci inh_flags = dest->inh_flags | src->inh_flags; 162e1051a39Sopenharmony_ci 163e1051a39Sopenharmony_ci if ((inh_flags & X509_VP_FLAG_ONCE) != 0) 164e1051a39Sopenharmony_ci dest->inh_flags = 0; 165e1051a39Sopenharmony_ci 166e1051a39Sopenharmony_ci if ((inh_flags & X509_VP_FLAG_LOCKED) != 0) 167e1051a39Sopenharmony_ci return 1; 168e1051a39Sopenharmony_ci 169e1051a39Sopenharmony_ci to_default = (inh_flags & X509_VP_FLAG_DEFAULT) != 0; 170e1051a39Sopenharmony_ci to_overwrite = (inh_flags & X509_VP_FLAG_OVERWRITE) != 0; 171e1051a39Sopenharmony_ci 172e1051a39Sopenharmony_ci x509_verify_param_copy(purpose, 0); 173e1051a39Sopenharmony_ci x509_verify_param_copy(trust, X509_TRUST_DEFAULT); 174e1051a39Sopenharmony_ci x509_verify_param_copy(depth, -1); 175e1051a39Sopenharmony_ci x509_verify_param_copy(auth_level, -1); 176e1051a39Sopenharmony_ci 177e1051a39Sopenharmony_ci /* If overwrite or check time not set, copy across */ 178e1051a39Sopenharmony_ci 179e1051a39Sopenharmony_ci if (to_overwrite || (dest->flags & X509_V_FLAG_USE_CHECK_TIME) == 0) { 180e1051a39Sopenharmony_ci dest->check_time = src->check_time; 181e1051a39Sopenharmony_ci dest->flags &= ~X509_V_FLAG_USE_CHECK_TIME; 182e1051a39Sopenharmony_ci /* Don't need to copy flag: that is done below */ 183e1051a39Sopenharmony_ci } 184e1051a39Sopenharmony_ci 185e1051a39Sopenharmony_ci if ((inh_flags & X509_VP_FLAG_RESET_FLAGS) != 0) 186e1051a39Sopenharmony_ci dest->flags = 0; 187e1051a39Sopenharmony_ci 188e1051a39Sopenharmony_ci dest->flags |= src->flags; 189e1051a39Sopenharmony_ci 190e1051a39Sopenharmony_ci if (test_x509_verify_param_copy(policies, NULL)) { 191e1051a39Sopenharmony_ci if (!X509_VERIFY_PARAM_set1_policies(dest, src->policies)) 192e1051a39Sopenharmony_ci return 0; 193e1051a39Sopenharmony_ci } 194e1051a39Sopenharmony_ci 195e1051a39Sopenharmony_ci x509_verify_param_copy(hostflags, 0); 196e1051a39Sopenharmony_ci 197e1051a39Sopenharmony_ci if (test_x509_verify_param_copy(hosts, NULL)) { 198e1051a39Sopenharmony_ci sk_OPENSSL_STRING_pop_free(dest->hosts, str_free); 199e1051a39Sopenharmony_ci dest->hosts = NULL; 200e1051a39Sopenharmony_ci if (src->hosts != NULL) { 201e1051a39Sopenharmony_ci dest->hosts = 202e1051a39Sopenharmony_ci sk_OPENSSL_STRING_deep_copy(src->hosts, str_copy, str_free); 203e1051a39Sopenharmony_ci if (dest->hosts == NULL) 204e1051a39Sopenharmony_ci return 0; 205e1051a39Sopenharmony_ci } 206e1051a39Sopenharmony_ci } 207e1051a39Sopenharmony_ci 208e1051a39Sopenharmony_ci if (test_x509_verify_param_copy(email, NULL)) { 209e1051a39Sopenharmony_ci if (!X509_VERIFY_PARAM_set1_email(dest, src->email, src->emaillen)) 210e1051a39Sopenharmony_ci return 0; 211e1051a39Sopenharmony_ci } 212e1051a39Sopenharmony_ci 213e1051a39Sopenharmony_ci if (test_x509_verify_param_copy(ip, NULL)) { 214e1051a39Sopenharmony_ci if (!X509_VERIFY_PARAM_set1_ip(dest, src->ip, src->iplen)) 215e1051a39Sopenharmony_ci return 0; 216e1051a39Sopenharmony_ci } 217e1051a39Sopenharmony_ci 218e1051a39Sopenharmony_ci return 1; 219e1051a39Sopenharmony_ci} 220e1051a39Sopenharmony_ci 221e1051a39Sopenharmony_ciint X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, 222e1051a39Sopenharmony_ci const X509_VERIFY_PARAM *from) 223e1051a39Sopenharmony_ci{ 224e1051a39Sopenharmony_ci unsigned long save_flags; 225e1051a39Sopenharmony_ci int ret; 226e1051a39Sopenharmony_ci 227e1051a39Sopenharmony_ci if (to == NULL) { 228e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); 229e1051a39Sopenharmony_ci return 0; 230e1051a39Sopenharmony_ci } 231e1051a39Sopenharmony_ci save_flags = to->inh_flags; 232e1051a39Sopenharmony_ci to->inh_flags |= X509_VP_FLAG_DEFAULT; 233e1051a39Sopenharmony_ci ret = X509_VERIFY_PARAM_inherit(to, from); 234e1051a39Sopenharmony_ci to->inh_flags = save_flags; 235e1051a39Sopenharmony_ci return ret; 236e1051a39Sopenharmony_ci} 237e1051a39Sopenharmony_ci 238e1051a39Sopenharmony_cistatic int int_x509_param_set1(char **pdest, size_t *pdestlen, 239e1051a39Sopenharmony_ci const char *src, size_t srclen) 240e1051a39Sopenharmony_ci{ 241e1051a39Sopenharmony_ci char *tmp; 242e1051a39Sopenharmony_ci 243e1051a39Sopenharmony_ci if (src != NULL) { 244e1051a39Sopenharmony_ci if (srclen == 0) 245e1051a39Sopenharmony_ci srclen = strlen(src); 246e1051a39Sopenharmony_ci 247e1051a39Sopenharmony_ci tmp = OPENSSL_malloc(srclen + 1); 248e1051a39Sopenharmony_ci if (tmp == NULL) 249e1051a39Sopenharmony_ci return 0; 250e1051a39Sopenharmony_ci memcpy(tmp, src, srclen); 251e1051a39Sopenharmony_ci tmp[srclen] = '\0'; /* enforce NUL termination */ 252e1051a39Sopenharmony_ci } else { 253e1051a39Sopenharmony_ci tmp = NULL; 254e1051a39Sopenharmony_ci srclen = 0; 255e1051a39Sopenharmony_ci } 256e1051a39Sopenharmony_ci OPENSSL_free(*pdest); 257e1051a39Sopenharmony_ci *pdest = tmp; 258e1051a39Sopenharmony_ci if (pdestlen != NULL) 259e1051a39Sopenharmony_ci *pdestlen = srclen; 260e1051a39Sopenharmony_ci return 1; 261e1051a39Sopenharmony_ci} 262e1051a39Sopenharmony_ci 263e1051a39Sopenharmony_ciint X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name) 264e1051a39Sopenharmony_ci{ 265e1051a39Sopenharmony_ci OPENSSL_free(param->name); 266e1051a39Sopenharmony_ci param->name = OPENSSL_strdup(name); 267e1051a39Sopenharmony_ci return param->name != NULL; 268e1051a39Sopenharmony_ci} 269e1051a39Sopenharmony_ci 270e1051a39Sopenharmony_ciint X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags) 271e1051a39Sopenharmony_ci{ 272e1051a39Sopenharmony_ci param->flags |= flags; 273e1051a39Sopenharmony_ci if ((flags & X509_V_FLAG_POLICY_MASK) != 0) 274e1051a39Sopenharmony_ci param->flags |= X509_V_FLAG_POLICY_CHECK; 275e1051a39Sopenharmony_ci return 1; 276e1051a39Sopenharmony_ci} 277e1051a39Sopenharmony_ci 278e1051a39Sopenharmony_ciint X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, 279e1051a39Sopenharmony_ci unsigned long flags) 280e1051a39Sopenharmony_ci{ 281e1051a39Sopenharmony_ci param->flags &= ~flags; 282e1051a39Sopenharmony_ci return 1; 283e1051a39Sopenharmony_ci} 284e1051a39Sopenharmony_ci 285e1051a39Sopenharmony_ciunsigned long X509_VERIFY_PARAM_get_flags(const X509_VERIFY_PARAM *param) 286e1051a39Sopenharmony_ci{ 287e1051a39Sopenharmony_ci return param->flags; 288e1051a39Sopenharmony_ci} 289e1051a39Sopenharmony_ci 290e1051a39Sopenharmony_ciuint32_t X509_VERIFY_PARAM_get_inh_flags(const X509_VERIFY_PARAM *param) 291e1051a39Sopenharmony_ci{ 292e1051a39Sopenharmony_ci return param->inh_flags; 293e1051a39Sopenharmony_ci} 294e1051a39Sopenharmony_ci 295e1051a39Sopenharmony_ciint X509_VERIFY_PARAM_set_inh_flags(X509_VERIFY_PARAM *param, uint32_t flags) 296e1051a39Sopenharmony_ci{ 297e1051a39Sopenharmony_ci param->inh_flags = flags; 298e1051a39Sopenharmony_ci return 1; 299e1051a39Sopenharmony_ci} 300e1051a39Sopenharmony_ci 301e1051a39Sopenharmony_ciint X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose) 302e1051a39Sopenharmony_ci{ 303e1051a39Sopenharmony_ci return X509_PURPOSE_set(¶m->purpose, purpose); 304e1051a39Sopenharmony_ci} 305e1051a39Sopenharmony_ci 306e1051a39Sopenharmony_ciint X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust) 307e1051a39Sopenharmony_ci{ 308e1051a39Sopenharmony_ci return X509_TRUST_set(¶m->trust, trust); 309e1051a39Sopenharmony_ci} 310e1051a39Sopenharmony_ci 311e1051a39Sopenharmony_civoid X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth) 312e1051a39Sopenharmony_ci{ 313e1051a39Sopenharmony_ci param->depth = depth; 314e1051a39Sopenharmony_ci} 315e1051a39Sopenharmony_ci 316e1051a39Sopenharmony_civoid X509_VERIFY_PARAM_set_auth_level(X509_VERIFY_PARAM *param, int auth_level) 317e1051a39Sopenharmony_ci{ 318e1051a39Sopenharmony_ci param->auth_level = auth_level; 319e1051a39Sopenharmony_ci} 320e1051a39Sopenharmony_ci 321e1051a39Sopenharmony_citime_t X509_VERIFY_PARAM_get_time(const X509_VERIFY_PARAM *param) 322e1051a39Sopenharmony_ci{ 323e1051a39Sopenharmony_ci return param->check_time; 324e1051a39Sopenharmony_ci} 325e1051a39Sopenharmony_ci 326e1051a39Sopenharmony_civoid X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t) 327e1051a39Sopenharmony_ci{ 328e1051a39Sopenharmony_ci param->check_time = t; 329e1051a39Sopenharmony_ci param->flags |= X509_V_FLAG_USE_CHECK_TIME; 330e1051a39Sopenharmony_ci} 331e1051a39Sopenharmony_ci 332e1051a39Sopenharmony_ciint X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, 333e1051a39Sopenharmony_ci ASN1_OBJECT *policy) 334e1051a39Sopenharmony_ci{ 335e1051a39Sopenharmony_ci if (param->policies == NULL) { 336e1051a39Sopenharmony_ci param->policies = sk_ASN1_OBJECT_new_null(); 337e1051a39Sopenharmony_ci if (param->policies == NULL) 338e1051a39Sopenharmony_ci return 0; 339e1051a39Sopenharmony_ci } 340e1051a39Sopenharmony_ci return sk_ASN1_OBJECT_push(param->policies, policy); 341e1051a39Sopenharmony_ci} 342e1051a39Sopenharmony_ci 343e1051a39Sopenharmony_ciint X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, 344e1051a39Sopenharmony_ci STACK_OF(ASN1_OBJECT) *policies) 345e1051a39Sopenharmony_ci{ 346e1051a39Sopenharmony_ci int i; 347e1051a39Sopenharmony_ci ASN1_OBJECT *oid, *doid; 348e1051a39Sopenharmony_ci 349e1051a39Sopenharmony_ci if (param == NULL) { 350e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); 351e1051a39Sopenharmony_ci return 0; 352e1051a39Sopenharmony_ci } 353e1051a39Sopenharmony_ci sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free); 354e1051a39Sopenharmony_ci 355e1051a39Sopenharmony_ci if (policies == NULL) { 356e1051a39Sopenharmony_ci param->policies = NULL; 357e1051a39Sopenharmony_ci return 1; 358e1051a39Sopenharmony_ci } 359e1051a39Sopenharmony_ci 360e1051a39Sopenharmony_ci param->policies = sk_ASN1_OBJECT_new_null(); 361e1051a39Sopenharmony_ci if (param->policies == NULL) 362e1051a39Sopenharmony_ci return 0; 363e1051a39Sopenharmony_ci 364e1051a39Sopenharmony_ci for (i = 0; i < sk_ASN1_OBJECT_num(policies); i++) { 365e1051a39Sopenharmony_ci oid = sk_ASN1_OBJECT_value(policies, i); 366e1051a39Sopenharmony_ci doid = OBJ_dup(oid); 367e1051a39Sopenharmony_ci if (doid == NULL) 368e1051a39Sopenharmony_ci return 0; 369e1051a39Sopenharmony_ci if (!sk_ASN1_OBJECT_push(param->policies, doid)) { 370e1051a39Sopenharmony_ci ASN1_OBJECT_free(doid); 371e1051a39Sopenharmony_ci return 0; 372e1051a39Sopenharmony_ci } 373e1051a39Sopenharmony_ci } 374e1051a39Sopenharmony_ci param->flags |= X509_V_FLAG_POLICY_CHECK; 375e1051a39Sopenharmony_ci return 1; 376e1051a39Sopenharmony_ci} 377e1051a39Sopenharmony_ci 378e1051a39Sopenharmony_cichar *X509_VERIFY_PARAM_get0_host(X509_VERIFY_PARAM *param, int idx) 379e1051a39Sopenharmony_ci{ 380e1051a39Sopenharmony_ci return sk_OPENSSL_STRING_value(param->hosts, idx); 381e1051a39Sopenharmony_ci} 382e1051a39Sopenharmony_ci 383e1051a39Sopenharmony_ciint X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param, 384e1051a39Sopenharmony_ci const char *name, size_t namelen) 385e1051a39Sopenharmony_ci{ 386e1051a39Sopenharmony_ci return int_x509_param_set_hosts(param, SET_HOST, name, namelen); 387e1051a39Sopenharmony_ci} 388e1051a39Sopenharmony_ci 389e1051a39Sopenharmony_ciint X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param, 390e1051a39Sopenharmony_ci const char *name, size_t namelen) 391e1051a39Sopenharmony_ci{ 392e1051a39Sopenharmony_ci return int_x509_param_set_hosts(param, ADD_HOST, name, namelen); 393e1051a39Sopenharmony_ci} 394e1051a39Sopenharmony_ci 395e1051a39Sopenharmony_civoid X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param, 396e1051a39Sopenharmony_ci unsigned int flags) 397e1051a39Sopenharmony_ci{ 398e1051a39Sopenharmony_ci param->hostflags = flags; 399e1051a39Sopenharmony_ci} 400e1051a39Sopenharmony_ci 401e1051a39Sopenharmony_ciunsigned int X509_VERIFY_PARAM_get_hostflags(const X509_VERIFY_PARAM *param) 402e1051a39Sopenharmony_ci{ 403e1051a39Sopenharmony_ci return param->hostflags; 404e1051a39Sopenharmony_ci} 405e1051a39Sopenharmony_ci 406e1051a39Sopenharmony_cichar *X509_VERIFY_PARAM_get0_peername(const X509_VERIFY_PARAM *param) 407e1051a39Sopenharmony_ci{ 408e1051a39Sopenharmony_ci return param->peername; 409e1051a39Sopenharmony_ci} 410e1051a39Sopenharmony_ci 411e1051a39Sopenharmony_ci/* 412e1051a39Sopenharmony_ci * Move peername from one param structure to another, freeing any name present 413e1051a39Sopenharmony_ci * at the target. If the source is a NULL parameter structure, free and zero 414e1051a39Sopenharmony_ci * the target peername. 415e1051a39Sopenharmony_ci */ 416e1051a39Sopenharmony_civoid X509_VERIFY_PARAM_move_peername(X509_VERIFY_PARAM *to, 417e1051a39Sopenharmony_ci X509_VERIFY_PARAM *from) 418e1051a39Sopenharmony_ci{ 419e1051a39Sopenharmony_ci char *peername = (from != NULL) ? from->peername : NULL; 420e1051a39Sopenharmony_ci 421e1051a39Sopenharmony_ci if (to->peername != peername) { 422e1051a39Sopenharmony_ci OPENSSL_free(to->peername); 423e1051a39Sopenharmony_ci to->peername = peername; 424e1051a39Sopenharmony_ci } 425e1051a39Sopenharmony_ci if (from != NULL) 426e1051a39Sopenharmony_ci from->peername = NULL; 427e1051a39Sopenharmony_ci} 428e1051a39Sopenharmony_ci 429e1051a39Sopenharmony_cichar *X509_VERIFY_PARAM_get0_email(X509_VERIFY_PARAM *param) 430e1051a39Sopenharmony_ci{ 431e1051a39Sopenharmony_ci return param->email; 432e1051a39Sopenharmony_ci} 433e1051a39Sopenharmony_ci 434e1051a39Sopenharmony_ciint X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, 435e1051a39Sopenharmony_ci const char *email, size_t emaillen) 436e1051a39Sopenharmony_ci{ 437e1051a39Sopenharmony_ci return int_x509_param_set1(¶m->email, ¶m->emaillen, 438e1051a39Sopenharmony_ci email, emaillen); 439e1051a39Sopenharmony_ci} 440e1051a39Sopenharmony_ci 441e1051a39Sopenharmony_cistatic unsigned char 442e1051a39Sopenharmony_ci*int_X509_VERIFY_PARAM_get0_ip(X509_VERIFY_PARAM *param, size_t *plen) 443e1051a39Sopenharmony_ci{ 444e1051a39Sopenharmony_ci if (param == NULL || param->ip == NULL) { 445e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); 446e1051a39Sopenharmony_ci return NULL; 447e1051a39Sopenharmony_ci } 448e1051a39Sopenharmony_ci if (plen != NULL) 449e1051a39Sopenharmony_ci *plen = param->iplen; 450e1051a39Sopenharmony_ci return param->ip; 451e1051a39Sopenharmony_ci} 452e1051a39Sopenharmony_ci 453e1051a39Sopenharmony_cichar *X509_VERIFY_PARAM_get1_ip_asc(X509_VERIFY_PARAM *param) 454e1051a39Sopenharmony_ci{ 455e1051a39Sopenharmony_ci size_t iplen; 456e1051a39Sopenharmony_ci unsigned char *ip = int_X509_VERIFY_PARAM_get0_ip(param, &iplen); 457e1051a39Sopenharmony_ci 458e1051a39Sopenharmony_ci return ip == NULL ? NULL : ossl_ipaddr_to_asc(ip, iplen); 459e1051a39Sopenharmony_ci} 460e1051a39Sopenharmony_ci 461e1051a39Sopenharmony_ciint X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, 462e1051a39Sopenharmony_ci const unsigned char *ip, size_t iplen) 463e1051a39Sopenharmony_ci{ 464e1051a39Sopenharmony_ci if (iplen != 0 && iplen != 4 && iplen != 16) { 465e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_X509, ERR_R_PASSED_INVALID_ARGUMENT); 466e1051a39Sopenharmony_ci return 0; 467e1051a39Sopenharmony_ci } 468e1051a39Sopenharmony_ci return int_x509_param_set1((char **)¶m->ip, ¶m->iplen, 469e1051a39Sopenharmony_ci (char *)ip, iplen); 470e1051a39Sopenharmony_ci} 471e1051a39Sopenharmony_ci 472e1051a39Sopenharmony_ciint X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, const char *ipasc) 473e1051a39Sopenharmony_ci{ 474e1051a39Sopenharmony_ci unsigned char ipout[16]; 475e1051a39Sopenharmony_ci size_t iplen = (size_t)ossl_a2i_ipadd(ipout, ipasc); 476e1051a39Sopenharmony_ci 477e1051a39Sopenharmony_ci if (iplen == 0) 478e1051a39Sopenharmony_ci return 0; 479e1051a39Sopenharmony_ci return X509_VERIFY_PARAM_set1_ip(param, ipout, iplen); 480e1051a39Sopenharmony_ci} 481e1051a39Sopenharmony_ci 482e1051a39Sopenharmony_ciint X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param) 483e1051a39Sopenharmony_ci{ 484e1051a39Sopenharmony_ci return param->depth; 485e1051a39Sopenharmony_ci} 486e1051a39Sopenharmony_ci 487e1051a39Sopenharmony_ciint X509_VERIFY_PARAM_get_auth_level(const X509_VERIFY_PARAM *param) 488e1051a39Sopenharmony_ci{ 489e1051a39Sopenharmony_ci return param->auth_level; 490e1051a39Sopenharmony_ci} 491e1051a39Sopenharmony_ci 492e1051a39Sopenharmony_ciconst char *X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param) 493e1051a39Sopenharmony_ci{ 494e1051a39Sopenharmony_ci return param->name; 495e1051a39Sopenharmony_ci} 496e1051a39Sopenharmony_ci 497e1051a39Sopenharmony_ci#define vpm_empty_id NULL, 0U, NULL, NULL, 0, NULL, 0 498e1051a39Sopenharmony_ci 499e1051a39Sopenharmony_ci/* 500e1051a39Sopenharmony_ci * Default verify parameters: these are used for various applications and can 501e1051a39Sopenharmony_ci * be overridden by the user specified table. NB: the 'name' field *must* be 502e1051a39Sopenharmony_ci * in alphabetical order because it will be searched using OBJ_search. 503e1051a39Sopenharmony_ci */ 504e1051a39Sopenharmony_ci 505e1051a39Sopenharmony_cistatic const X509_VERIFY_PARAM default_table[] = { 506e1051a39Sopenharmony_ci { 507e1051a39Sopenharmony_ci "default", /* X509 default parameters */ 508e1051a39Sopenharmony_ci 0, /* check time to use */ 509e1051a39Sopenharmony_ci 0, /* inheritance flags */ 510e1051a39Sopenharmony_ci X509_V_FLAG_TRUSTED_FIRST, /* flags */ 511e1051a39Sopenharmony_ci 0, /* purpose */ 512e1051a39Sopenharmony_ci 0, /* trust */ 513e1051a39Sopenharmony_ci 100, /* depth */ 514e1051a39Sopenharmony_ci -1, /* auth_level */ 515e1051a39Sopenharmony_ci NULL, /* policies */ 516e1051a39Sopenharmony_ci vpm_empty_id}, 517e1051a39Sopenharmony_ci { 518e1051a39Sopenharmony_ci "pkcs7", /* S/MIME sign parameters */ 519e1051a39Sopenharmony_ci 0, /* check time to use */ 520e1051a39Sopenharmony_ci 0, /* inheritance flags */ 521e1051a39Sopenharmony_ci 0, /* flags */ 522e1051a39Sopenharmony_ci X509_PURPOSE_SMIME_SIGN, /* purpose */ 523e1051a39Sopenharmony_ci X509_TRUST_EMAIL, /* trust */ 524e1051a39Sopenharmony_ci -1, /* depth */ 525e1051a39Sopenharmony_ci -1, /* auth_level */ 526e1051a39Sopenharmony_ci NULL, /* policies */ 527e1051a39Sopenharmony_ci vpm_empty_id}, 528e1051a39Sopenharmony_ci { 529e1051a39Sopenharmony_ci "smime_sign", /* S/MIME sign parameters */ 530e1051a39Sopenharmony_ci 0, /* check time to use */ 531e1051a39Sopenharmony_ci 0, /* inheritance flags */ 532e1051a39Sopenharmony_ci 0, /* flags */ 533e1051a39Sopenharmony_ci X509_PURPOSE_SMIME_SIGN, /* purpose */ 534e1051a39Sopenharmony_ci X509_TRUST_EMAIL, /* trust */ 535e1051a39Sopenharmony_ci -1, /* depth */ 536e1051a39Sopenharmony_ci -1, /* auth_level */ 537e1051a39Sopenharmony_ci NULL, /* policies */ 538e1051a39Sopenharmony_ci vpm_empty_id}, 539e1051a39Sopenharmony_ci { 540e1051a39Sopenharmony_ci "ssl_client", /* SSL/TLS client parameters */ 541e1051a39Sopenharmony_ci 0, /* check time to use */ 542e1051a39Sopenharmony_ci 0, /* inheritance flags */ 543e1051a39Sopenharmony_ci 0, /* flags */ 544e1051a39Sopenharmony_ci X509_PURPOSE_SSL_CLIENT, /* purpose */ 545e1051a39Sopenharmony_ci X509_TRUST_SSL_CLIENT, /* trust */ 546e1051a39Sopenharmony_ci -1, /* depth */ 547e1051a39Sopenharmony_ci -1, /* auth_level */ 548e1051a39Sopenharmony_ci NULL, /* policies */ 549e1051a39Sopenharmony_ci vpm_empty_id}, 550e1051a39Sopenharmony_ci { 551e1051a39Sopenharmony_ci "ssl_server", /* SSL/TLS server parameters */ 552e1051a39Sopenharmony_ci 0, /* check time to use */ 553e1051a39Sopenharmony_ci 0, /* inheritance flags */ 554e1051a39Sopenharmony_ci 0, /* flags */ 555e1051a39Sopenharmony_ci X509_PURPOSE_SSL_SERVER, /* purpose */ 556e1051a39Sopenharmony_ci X509_TRUST_SSL_SERVER, /* trust */ 557e1051a39Sopenharmony_ci -1, /* depth */ 558e1051a39Sopenharmony_ci -1, /* auth_level */ 559e1051a39Sopenharmony_ci NULL, /* policies */ 560e1051a39Sopenharmony_ci vpm_empty_id} 561e1051a39Sopenharmony_ci}; 562e1051a39Sopenharmony_ci 563e1051a39Sopenharmony_cistatic STACK_OF(X509_VERIFY_PARAM) *param_table = NULL; 564e1051a39Sopenharmony_ci 565e1051a39Sopenharmony_cistatic int table_cmp(const X509_VERIFY_PARAM *a, const X509_VERIFY_PARAM *b) 566e1051a39Sopenharmony_ci{ 567e1051a39Sopenharmony_ci return strcmp(a->name, b->name); 568e1051a39Sopenharmony_ci} 569e1051a39Sopenharmony_ci 570e1051a39Sopenharmony_ciDECLARE_OBJ_BSEARCH_CMP_FN(X509_VERIFY_PARAM, X509_VERIFY_PARAM, table); 571e1051a39Sopenharmony_ciIMPLEMENT_OBJ_BSEARCH_CMP_FN(X509_VERIFY_PARAM, X509_VERIFY_PARAM, table); 572e1051a39Sopenharmony_ci 573e1051a39Sopenharmony_cistatic int param_cmp(const X509_VERIFY_PARAM *const *a, 574e1051a39Sopenharmony_ci const X509_VERIFY_PARAM *const *b) 575e1051a39Sopenharmony_ci{ 576e1051a39Sopenharmony_ci return strcmp((*a)->name, (*b)->name); 577e1051a39Sopenharmony_ci} 578e1051a39Sopenharmony_ci 579e1051a39Sopenharmony_ciint X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param) 580e1051a39Sopenharmony_ci{ 581e1051a39Sopenharmony_ci int idx; 582e1051a39Sopenharmony_ci X509_VERIFY_PARAM *ptmp; 583e1051a39Sopenharmony_ci 584e1051a39Sopenharmony_ci if (param_table == NULL) { 585e1051a39Sopenharmony_ci param_table = sk_X509_VERIFY_PARAM_new(param_cmp); 586e1051a39Sopenharmony_ci if (param_table == NULL) 587e1051a39Sopenharmony_ci return 0; 588e1051a39Sopenharmony_ci } else { 589e1051a39Sopenharmony_ci idx = sk_X509_VERIFY_PARAM_find(param_table, param); 590e1051a39Sopenharmony_ci if (idx >= 0) { 591e1051a39Sopenharmony_ci ptmp = sk_X509_VERIFY_PARAM_delete(param_table, idx); 592e1051a39Sopenharmony_ci X509_VERIFY_PARAM_free(ptmp); 593e1051a39Sopenharmony_ci } 594e1051a39Sopenharmony_ci } 595e1051a39Sopenharmony_ci return sk_X509_VERIFY_PARAM_push(param_table, param); 596e1051a39Sopenharmony_ci} 597e1051a39Sopenharmony_ci 598e1051a39Sopenharmony_ciint X509_VERIFY_PARAM_get_count(void) 599e1051a39Sopenharmony_ci{ 600e1051a39Sopenharmony_ci int num = OSSL_NELEM(default_table); 601e1051a39Sopenharmony_ci 602e1051a39Sopenharmony_ci if (param_table != NULL) 603e1051a39Sopenharmony_ci num += sk_X509_VERIFY_PARAM_num(param_table); 604e1051a39Sopenharmony_ci return num; 605e1051a39Sopenharmony_ci} 606e1051a39Sopenharmony_ci 607e1051a39Sopenharmony_ciconst X509_VERIFY_PARAM *X509_VERIFY_PARAM_get0(int id) 608e1051a39Sopenharmony_ci{ 609e1051a39Sopenharmony_ci int num = OSSL_NELEM(default_table); 610e1051a39Sopenharmony_ci 611e1051a39Sopenharmony_ci if (id < num) 612e1051a39Sopenharmony_ci return default_table + id; 613e1051a39Sopenharmony_ci return sk_X509_VERIFY_PARAM_value(param_table, id - num); 614e1051a39Sopenharmony_ci} 615e1051a39Sopenharmony_ci 616e1051a39Sopenharmony_ciconst X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name) 617e1051a39Sopenharmony_ci{ 618e1051a39Sopenharmony_ci int idx; 619e1051a39Sopenharmony_ci X509_VERIFY_PARAM pm; 620e1051a39Sopenharmony_ci 621e1051a39Sopenharmony_ci pm.name = (char *)name; 622e1051a39Sopenharmony_ci if (param_table != NULL) { 623e1051a39Sopenharmony_ci idx = sk_X509_VERIFY_PARAM_find(param_table, &pm); 624e1051a39Sopenharmony_ci if (idx >= 0) 625e1051a39Sopenharmony_ci return sk_X509_VERIFY_PARAM_value(param_table, idx); 626e1051a39Sopenharmony_ci } 627e1051a39Sopenharmony_ci return OBJ_bsearch_table(&pm, default_table, OSSL_NELEM(default_table)); 628e1051a39Sopenharmony_ci} 629e1051a39Sopenharmony_ci 630e1051a39Sopenharmony_civoid X509_VERIFY_PARAM_table_cleanup(void) 631e1051a39Sopenharmony_ci{ 632e1051a39Sopenharmony_ci sk_X509_VERIFY_PARAM_pop_free(param_table, X509_VERIFY_PARAM_free); 633e1051a39Sopenharmony_ci param_table = NULL; 634e1051a39Sopenharmony_ci} 635