1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 1999-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 "internal/cryptlib.h" 12e1051a39Sopenharmony_ci#include <openssl/conf.h> 13e1051a39Sopenharmony_ci#include <openssl/asn1.h> 14e1051a39Sopenharmony_ci#include <openssl/asn1t.h> 15e1051a39Sopenharmony_ci#include <openssl/x509v3.h> 16e1051a39Sopenharmony_ci#include "ext_dat.h" 17e1051a39Sopenharmony_ci 18e1051a39Sopenharmony_ci/* Support for Thawte strong extranet extension */ 19e1051a39Sopenharmony_ci 20e1051a39Sopenharmony_ci#define SXNET_TEST 21e1051a39Sopenharmony_ci 22e1051a39Sopenharmony_cistatic int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out, 23e1051a39Sopenharmony_ci int indent); 24e1051a39Sopenharmony_ci#ifdef SXNET_TEST 25e1051a39Sopenharmony_cistatic SXNET *sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, 26e1051a39Sopenharmony_ci STACK_OF(CONF_VALUE) *nval); 27e1051a39Sopenharmony_ci#endif 28e1051a39Sopenharmony_ciconst X509V3_EXT_METHOD ossl_v3_sxnet = { 29e1051a39Sopenharmony_ci NID_sxnet, X509V3_EXT_MULTILINE, ASN1_ITEM_ref(SXNET), 30e1051a39Sopenharmony_ci 0, 0, 0, 0, 31e1051a39Sopenharmony_ci 0, 0, 32e1051a39Sopenharmony_ci 0, 33e1051a39Sopenharmony_ci#ifdef SXNET_TEST 34e1051a39Sopenharmony_ci (X509V3_EXT_V2I)sxnet_v2i, 35e1051a39Sopenharmony_ci#else 36e1051a39Sopenharmony_ci 0, 37e1051a39Sopenharmony_ci#endif 38e1051a39Sopenharmony_ci (X509V3_EXT_I2R)sxnet_i2r, 39e1051a39Sopenharmony_ci 0, 40e1051a39Sopenharmony_ci NULL 41e1051a39Sopenharmony_ci}; 42e1051a39Sopenharmony_ci 43e1051a39Sopenharmony_ciASN1_SEQUENCE(SXNETID) = { 44e1051a39Sopenharmony_ci ASN1_SIMPLE(SXNETID, zone, ASN1_INTEGER), 45e1051a39Sopenharmony_ci ASN1_SIMPLE(SXNETID, user, ASN1_OCTET_STRING) 46e1051a39Sopenharmony_ci} ASN1_SEQUENCE_END(SXNETID) 47e1051a39Sopenharmony_ci 48e1051a39Sopenharmony_ciIMPLEMENT_ASN1_FUNCTIONS(SXNETID) 49e1051a39Sopenharmony_ci 50e1051a39Sopenharmony_ciASN1_SEQUENCE(SXNET) = { 51e1051a39Sopenharmony_ci ASN1_SIMPLE(SXNET, version, ASN1_INTEGER), 52e1051a39Sopenharmony_ci ASN1_SEQUENCE_OF(SXNET, ids, SXNETID) 53e1051a39Sopenharmony_ci} ASN1_SEQUENCE_END(SXNET) 54e1051a39Sopenharmony_ci 55e1051a39Sopenharmony_ciIMPLEMENT_ASN1_FUNCTIONS(SXNET) 56e1051a39Sopenharmony_ci 57e1051a39Sopenharmony_cistatic int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out, 58e1051a39Sopenharmony_ci int indent) 59e1051a39Sopenharmony_ci{ 60e1051a39Sopenharmony_ci int64_t v; 61e1051a39Sopenharmony_ci char *tmp; 62e1051a39Sopenharmony_ci SXNETID *id; 63e1051a39Sopenharmony_ci int i; 64e1051a39Sopenharmony_ci 65e1051a39Sopenharmony_ci /* 66e1051a39Sopenharmony_ci * Since we add 1 to the version number to display it, we don't support 67e1051a39Sopenharmony_ci * LONG_MAX since that would cause on overflow. 68e1051a39Sopenharmony_ci */ 69e1051a39Sopenharmony_ci if (!ASN1_INTEGER_get_int64(&v, sx->version) 70e1051a39Sopenharmony_ci || v >= LONG_MAX 71e1051a39Sopenharmony_ci || v < LONG_MIN) { 72e1051a39Sopenharmony_ci BIO_printf(out, "%*sVersion: <unsupported>", indent, ""); 73e1051a39Sopenharmony_ci } else { 74e1051a39Sopenharmony_ci long vl = (long)v; 75e1051a39Sopenharmony_ci 76e1051a39Sopenharmony_ci BIO_printf(out, "%*sVersion: %ld (0x%lX)", indent, "", vl + 1, vl); 77e1051a39Sopenharmony_ci } 78e1051a39Sopenharmony_ci for (i = 0; i < sk_SXNETID_num(sx->ids); i++) { 79e1051a39Sopenharmony_ci id = sk_SXNETID_value(sx->ids, i); 80e1051a39Sopenharmony_ci tmp = i2s_ASN1_INTEGER(NULL, id->zone); 81e1051a39Sopenharmony_ci if (tmp == NULL) 82e1051a39Sopenharmony_ci return 0; 83e1051a39Sopenharmony_ci BIO_printf(out, "\n%*sZone: %s, User: ", indent, "", tmp); 84e1051a39Sopenharmony_ci OPENSSL_free(tmp); 85e1051a39Sopenharmony_ci ASN1_STRING_print(out, id->user); 86e1051a39Sopenharmony_ci } 87e1051a39Sopenharmony_ci return 1; 88e1051a39Sopenharmony_ci} 89e1051a39Sopenharmony_ci 90e1051a39Sopenharmony_ci#ifdef SXNET_TEST 91e1051a39Sopenharmony_ci 92e1051a39Sopenharmony_ci/* 93e1051a39Sopenharmony_ci * NBB: this is used for testing only. It should *not* be used for anything 94e1051a39Sopenharmony_ci * else because it will just take static IDs from the configuration file and 95e1051a39Sopenharmony_ci * they should really be separate values for each user. 96e1051a39Sopenharmony_ci */ 97e1051a39Sopenharmony_ci 98e1051a39Sopenharmony_cistatic SXNET *sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, 99e1051a39Sopenharmony_ci STACK_OF(CONF_VALUE) *nval) 100e1051a39Sopenharmony_ci{ 101e1051a39Sopenharmony_ci CONF_VALUE *cnf; 102e1051a39Sopenharmony_ci SXNET *sx = NULL; 103e1051a39Sopenharmony_ci int i; 104e1051a39Sopenharmony_ci for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { 105e1051a39Sopenharmony_ci cnf = sk_CONF_VALUE_value(nval, i); 106e1051a39Sopenharmony_ci if (!SXNET_add_id_asc(&sx, cnf->name, cnf->value, -1)) { 107e1051a39Sopenharmony_ci SXNET_free(sx); 108e1051a39Sopenharmony_ci return NULL; 109e1051a39Sopenharmony_ci } 110e1051a39Sopenharmony_ci } 111e1051a39Sopenharmony_ci return sx; 112e1051a39Sopenharmony_ci} 113e1051a39Sopenharmony_ci 114e1051a39Sopenharmony_ci#endif 115e1051a39Sopenharmony_ci 116e1051a39Sopenharmony_ci/* Strong Extranet utility functions */ 117e1051a39Sopenharmony_ci 118e1051a39Sopenharmony_ci/* Add an id given the zone as an ASCII number */ 119e1051a39Sopenharmony_ci 120e1051a39Sopenharmony_ciint SXNET_add_id_asc(SXNET **psx, const char *zone, const char *user, int userlen) 121e1051a39Sopenharmony_ci{ 122e1051a39Sopenharmony_ci ASN1_INTEGER *izone; 123e1051a39Sopenharmony_ci 124e1051a39Sopenharmony_ci if ((izone = s2i_ASN1_INTEGER(NULL, zone)) == NULL) { 125e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_X509V3, X509V3_R_ERROR_CONVERTING_ZONE); 126e1051a39Sopenharmony_ci return 0; 127e1051a39Sopenharmony_ci } 128e1051a39Sopenharmony_ci return SXNET_add_id_INTEGER(psx, izone, user, userlen); 129e1051a39Sopenharmony_ci} 130e1051a39Sopenharmony_ci 131e1051a39Sopenharmony_ci/* Add an id given the zone as an unsigned long */ 132e1051a39Sopenharmony_ci 133e1051a39Sopenharmony_ciint SXNET_add_id_ulong(SXNET **psx, unsigned long lzone, const char *user, 134e1051a39Sopenharmony_ci int userlen) 135e1051a39Sopenharmony_ci{ 136e1051a39Sopenharmony_ci ASN1_INTEGER *izone; 137e1051a39Sopenharmony_ci 138e1051a39Sopenharmony_ci if ((izone = ASN1_INTEGER_new()) == NULL 139e1051a39Sopenharmony_ci || !ASN1_INTEGER_set(izone, lzone)) { 140e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); 141e1051a39Sopenharmony_ci ASN1_INTEGER_free(izone); 142e1051a39Sopenharmony_ci return 0; 143e1051a39Sopenharmony_ci } 144e1051a39Sopenharmony_ci return SXNET_add_id_INTEGER(psx, izone, user, userlen); 145e1051a39Sopenharmony_ci 146e1051a39Sopenharmony_ci} 147e1051a39Sopenharmony_ci 148e1051a39Sopenharmony_ci/* 149e1051a39Sopenharmony_ci * Add an id given the zone as an ASN1_INTEGER. Note this version uses the 150e1051a39Sopenharmony_ci * passed integer and doesn't make a copy so don't free it up afterwards. 151e1051a39Sopenharmony_ci */ 152e1051a39Sopenharmony_ci 153e1051a39Sopenharmony_ciint SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *zone, const char *user, 154e1051a39Sopenharmony_ci int userlen) 155e1051a39Sopenharmony_ci{ 156e1051a39Sopenharmony_ci SXNET *sx = NULL; 157e1051a39Sopenharmony_ci SXNETID *id = NULL; 158e1051a39Sopenharmony_ci 159e1051a39Sopenharmony_ci if (psx == NULL || zone == NULL || user == NULL) { 160e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_NULL_ARGUMENT); 161e1051a39Sopenharmony_ci return 0; 162e1051a39Sopenharmony_ci } 163e1051a39Sopenharmony_ci if (userlen == -1) 164e1051a39Sopenharmony_ci userlen = strlen(user); 165e1051a39Sopenharmony_ci if (userlen > 64) { 166e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_X509V3, X509V3_R_USER_TOO_LONG); 167e1051a39Sopenharmony_ci return 0; 168e1051a39Sopenharmony_ci } 169e1051a39Sopenharmony_ci if (*psx == NULL) { 170e1051a39Sopenharmony_ci if ((sx = SXNET_new()) == NULL) 171e1051a39Sopenharmony_ci goto err; 172e1051a39Sopenharmony_ci if (!ASN1_INTEGER_set(sx->version, 0)) 173e1051a39Sopenharmony_ci goto err; 174e1051a39Sopenharmony_ci } else 175e1051a39Sopenharmony_ci sx = *psx; 176e1051a39Sopenharmony_ci if (SXNET_get_id_INTEGER(sx, zone)) { 177e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_X509V3, X509V3_R_DUPLICATE_ZONE_ID); 178e1051a39Sopenharmony_ci if (*psx == NULL) 179e1051a39Sopenharmony_ci SXNET_free(sx); 180e1051a39Sopenharmony_ci return 0; 181e1051a39Sopenharmony_ci } 182e1051a39Sopenharmony_ci 183e1051a39Sopenharmony_ci if ((id = SXNETID_new()) == NULL) 184e1051a39Sopenharmony_ci goto err; 185e1051a39Sopenharmony_ci if (userlen == -1) 186e1051a39Sopenharmony_ci userlen = strlen(user); 187e1051a39Sopenharmony_ci 188e1051a39Sopenharmony_ci if (!ASN1_OCTET_STRING_set(id->user, (const unsigned char *)user, userlen)) 189e1051a39Sopenharmony_ci goto err; 190e1051a39Sopenharmony_ci if (!sk_SXNETID_push(sx->ids, id)) 191e1051a39Sopenharmony_ci goto err; 192e1051a39Sopenharmony_ci ASN1_INTEGER_free(id->zone); 193e1051a39Sopenharmony_ci id->zone = zone; 194e1051a39Sopenharmony_ci *psx = sx; 195e1051a39Sopenharmony_ci return 1; 196e1051a39Sopenharmony_ci 197e1051a39Sopenharmony_ci err: 198e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); 199e1051a39Sopenharmony_ci SXNETID_free(id); 200e1051a39Sopenharmony_ci if (*psx == NULL) 201e1051a39Sopenharmony_ci SXNET_free(sx); 202e1051a39Sopenharmony_ci return 0; 203e1051a39Sopenharmony_ci} 204e1051a39Sopenharmony_ci 205e1051a39Sopenharmony_ciASN1_OCTET_STRING *SXNET_get_id_asc(SXNET *sx, const char *zone) 206e1051a39Sopenharmony_ci{ 207e1051a39Sopenharmony_ci ASN1_INTEGER *izone; 208e1051a39Sopenharmony_ci ASN1_OCTET_STRING *oct; 209e1051a39Sopenharmony_ci 210e1051a39Sopenharmony_ci if ((izone = s2i_ASN1_INTEGER(NULL, zone)) == NULL) { 211e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_X509V3, X509V3_R_ERROR_CONVERTING_ZONE); 212e1051a39Sopenharmony_ci return NULL; 213e1051a39Sopenharmony_ci } 214e1051a39Sopenharmony_ci oct = SXNET_get_id_INTEGER(sx, izone); 215e1051a39Sopenharmony_ci ASN1_INTEGER_free(izone); 216e1051a39Sopenharmony_ci return oct; 217e1051a39Sopenharmony_ci} 218e1051a39Sopenharmony_ci 219e1051a39Sopenharmony_ciASN1_OCTET_STRING *SXNET_get_id_ulong(SXNET *sx, unsigned long lzone) 220e1051a39Sopenharmony_ci{ 221e1051a39Sopenharmony_ci ASN1_INTEGER *izone; 222e1051a39Sopenharmony_ci ASN1_OCTET_STRING *oct; 223e1051a39Sopenharmony_ci 224e1051a39Sopenharmony_ci if ((izone = ASN1_INTEGER_new()) == NULL 225e1051a39Sopenharmony_ci || !ASN1_INTEGER_set(izone, lzone)) { 226e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); 227e1051a39Sopenharmony_ci ASN1_INTEGER_free(izone); 228e1051a39Sopenharmony_ci return NULL; 229e1051a39Sopenharmony_ci } 230e1051a39Sopenharmony_ci oct = SXNET_get_id_INTEGER(sx, izone); 231e1051a39Sopenharmony_ci ASN1_INTEGER_free(izone); 232e1051a39Sopenharmony_ci return oct; 233e1051a39Sopenharmony_ci} 234e1051a39Sopenharmony_ci 235e1051a39Sopenharmony_ciASN1_OCTET_STRING *SXNET_get_id_INTEGER(SXNET *sx, ASN1_INTEGER *zone) 236e1051a39Sopenharmony_ci{ 237e1051a39Sopenharmony_ci SXNETID *id; 238e1051a39Sopenharmony_ci int i; 239e1051a39Sopenharmony_ci for (i = 0; i < sk_SXNETID_num(sx->ids); i++) { 240e1051a39Sopenharmony_ci id = sk_SXNETID_value(sx->ids, i); 241e1051a39Sopenharmony_ci if (!ASN1_INTEGER_cmp(id->zone, zone)) 242e1051a39Sopenharmony_ci return id->user; 243e1051a39Sopenharmony_ci } 244e1051a39Sopenharmony_ci return NULL; 245e1051a39Sopenharmony_ci} 246