1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 1995-2021 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 <limits.h> 12e1051a39Sopenharmony_ci#include "internal/cryptlib.h" 13e1051a39Sopenharmony_ci#include <openssl/asn1.h> 14e1051a39Sopenharmony_ci#include "asn1_local.h" 15e1051a39Sopenharmony_ci 16e1051a39Sopenharmony_cistatic int asn1_get_length(const unsigned char **pp, int *inf, long *rl, 17e1051a39Sopenharmony_ci long max); 18e1051a39Sopenharmony_cistatic void asn1_put_length(unsigned char **pp, int length); 19e1051a39Sopenharmony_ci 20e1051a39Sopenharmony_cistatic int _asn1_check_infinite_end(const unsigned char **p, long len) 21e1051a39Sopenharmony_ci{ 22e1051a39Sopenharmony_ci /* 23e1051a39Sopenharmony_ci * If there is 0 or 1 byte left, the length check should pick things up 24e1051a39Sopenharmony_ci */ 25e1051a39Sopenharmony_ci if (len <= 0) { 26e1051a39Sopenharmony_ci return 1; 27e1051a39Sopenharmony_ci } else { 28e1051a39Sopenharmony_ci if ((len >= 2) && ((*p)[0] == 0) && ((*p)[1] == 0)) { 29e1051a39Sopenharmony_ci (*p) += 2; 30e1051a39Sopenharmony_ci return 1; 31e1051a39Sopenharmony_ci } 32e1051a39Sopenharmony_ci } 33e1051a39Sopenharmony_ci return 0; 34e1051a39Sopenharmony_ci} 35e1051a39Sopenharmony_ci 36e1051a39Sopenharmony_ciint ASN1_check_infinite_end(unsigned char **p, long len) 37e1051a39Sopenharmony_ci{ 38e1051a39Sopenharmony_ci return _asn1_check_infinite_end((const unsigned char **)p, len); 39e1051a39Sopenharmony_ci} 40e1051a39Sopenharmony_ci 41e1051a39Sopenharmony_ciint ASN1_const_check_infinite_end(const unsigned char **p, long len) 42e1051a39Sopenharmony_ci{ 43e1051a39Sopenharmony_ci return _asn1_check_infinite_end(p, len); 44e1051a39Sopenharmony_ci} 45e1051a39Sopenharmony_ci 46e1051a39Sopenharmony_ciint ASN1_get_object(const unsigned char **pp, long *plength, int *ptag, 47e1051a39Sopenharmony_ci int *pclass, long omax) 48e1051a39Sopenharmony_ci{ 49e1051a39Sopenharmony_ci int i, ret; 50e1051a39Sopenharmony_ci long len; 51e1051a39Sopenharmony_ci const unsigned char *p = *pp; 52e1051a39Sopenharmony_ci int tag, xclass, inf; 53e1051a39Sopenharmony_ci long max = omax; 54e1051a39Sopenharmony_ci 55e1051a39Sopenharmony_ci if (omax <= 0) { 56e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_SMALL); 57e1051a39Sopenharmony_ci return 0x80; 58e1051a39Sopenharmony_ci } 59e1051a39Sopenharmony_ci ret = (*p & V_ASN1_CONSTRUCTED); 60e1051a39Sopenharmony_ci xclass = (*p & V_ASN1_PRIVATE); 61e1051a39Sopenharmony_ci i = *p & V_ASN1_PRIMITIVE_TAG; 62e1051a39Sopenharmony_ci if (i == V_ASN1_PRIMITIVE_TAG) { /* high-tag */ 63e1051a39Sopenharmony_ci p++; 64e1051a39Sopenharmony_ci if (--max == 0) 65e1051a39Sopenharmony_ci goto err; 66e1051a39Sopenharmony_ci len = 0; 67e1051a39Sopenharmony_ci while (*p & 0x80) { 68e1051a39Sopenharmony_ci len <<= 7L; 69e1051a39Sopenharmony_ci len |= *(p++) & 0x7f; 70e1051a39Sopenharmony_ci if (--max == 0) 71e1051a39Sopenharmony_ci goto err; 72e1051a39Sopenharmony_ci if (len > (INT_MAX >> 7L)) 73e1051a39Sopenharmony_ci goto err; 74e1051a39Sopenharmony_ci } 75e1051a39Sopenharmony_ci len <<= 7L; 76e1051a39Sopenharmony_ci len |= *(p++) & 0x7f; 77e1051a39Sopenharmony_ci tag = (int)len; 78e1051a39Sopenharmony_ci if (--max == 0) 79e1051a39Sopenharmony_ci goto err; 80e1051a39Sopenharmony_ci } else { 81e1051a39Sopenharmony_ci tag = i; 82e1051a39Sopenharmony_ci p++; 83e1051a39Sopenharmony_ci if (--max == 0) 84e1051a39Sopenharmony_ci goto err; 85e1051a39Sopenharmony_ci } 86e1051a39Sopenharmony_ci *ptag = tag; 87e1051a39Sopenharmony_ci *pclass = xclass; 88e1051a39Sopenharmony_ci if (!asn1_get_length(&p, &inf, plength, max)) 89e1051a39Sopenharmony_ci goto err; 90e1051a39Sopenharmony_ci 91e1051a39Sopenharmony_ci if (inf && !(ret & V_ASN1_CONSTRUCTED)) 92e1051a39Sopenharmony_ci goto err; 93e1051a39Sopenharmony_ci 94e1051a39Sopenharmony_ci if (*plength > (omax - (p - *pp))) { 95e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_LONG); 96e1051a39Sopenharmony_ci /* 97e1051a39Sopenharmony_ci * Set this so that even if things are not long enough the values are 98e1051a39Sopenharmony_ci * set correctly 99e1051a39Sopenharmony_ci */ 100e1051a39Sopenharmony_ci ret |= 0x80; 101e1051a39Sopenharmony_ci } 102e1051a39Sopenharmony_ci *pp = p; 103e1051a39Sopenharmony_ci return ret | inf; 104e1051a39Sopenharmony_ci err: 105e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ASN1_R_HEADER_TOO_LONG); 106e1051a39Sopenharmony_ci return 0x80; 107e1051a39Sopenharmony_ci} 108e1051a39Sopenharmony_ci 109e1051a39Sopenharmony_ci/* 110e1051a39Sopenharmony_ci * Decode a length field. 111e1051a39Sopenharmony_ci * The short form is a single byte defining a length 0 - 127. 112e1051a39Sopenharmony_ci * The long form is a byte 0 - 127 with the top bit set and this indicates 113e1051a39Sopenharmony_ci * the number of following octets that contain the length. These octets 114e1051a39Sopenharmony_ci * are stored most significant digit first. 115e1051a39Sopenharmony_ci */ 116e1051a39Sopenharmony_cistatic int asn1_get_length(const unsigned char **pp, int *inf, long *rl, 117e1051a39Sopenharmony_ci long max) 118e1051a39Sopenharmony_ci{ 119e1051a39Sopenharmony_ci const unsigned char *p = *pp; 120e1051a39Sopenharmony_ci unsigned long ret = 0; 121e1051a39Sopenharmony_ci int i; 122e1051a39Sopenharmony_ci 123e1051a39Sopenharmony_ci if (max-- < 1) 124e1051a39Sopenharmony_ci return 0; 125e1051a39Sopenharmony_ci if (*p == 0x80) { 126e1051a39Sopenharmony_ci *inf = 1; 127e1051a39Sopenharmony_ci p++; 128e1051a39Sopenharmony_ci } else { 129e1051a39Sopenharmony_ci *inf = 0; 130e1051a39Sopenharmony_ci i = *p & 0x7f; 131e1051a39Sopenharmony_ci if (*p++ & 0x80) { 132e1051a39Sopenharmony_ci if (max < i + 1) 133e1051a39Sopenharmony_ci return 0; 134e1051a39Sopenharmony_ci /* Skip leading zeroes */ 135e1051a39Sopenharmony_ci while (i > 0 && *p == 0) { 136e1051a39Sopenharmony_ci p++; 137e1051a39Sopenharmony_ci i--; 138e1051a39Sopenharmony_ci } 139e1051a39Sopenharmony_ci if (i > (int)sizeof(long)) 140e1051a39Sopenharmony_ci return 0; 141e1051a39Sopenharmony_ci while (i > 0) { 142e1051a39Sopenharmony_ci ret <<= 8; 143e1051a39Sopenharmony_ci ret |= *p++; 144e1051a39Sopenharmony_ci i--; 145e1051a39Sopenharmony_ci } 146e1051a39Sopenharmony_ci if (ret > LONG_MAX) 147e1051a39Sopenharmony_ci return 0; 148e1051a39Sopenharmony_ci } else { 149e1051a39Sopenharmony_ci ret = i; 150e1051a39Sopenharmony_ci } 151e1051a39Sopenharmony_ci } 152e1051a39Sopenharmony_ci *pp = p; 153e1051a39Sopenharmony_ci *rl = (long)ret; 154e1051a39Sopenharmony_ci return 1; 155e1051a39Sopenharmony_ci} 156e1051a39Sopenharmony_ci 157e1051a39Sopenharmony_ci/* 158e1051a39Sopenharmony_ci * constructed == 2 for indefinite length constructed 159e1051a39Sopenharmony_ci */ 160e1051a39Sopenharmony_civoid ASN1_put_object(unsigned char **pp, int constructed, int length, int tag, 161e1051a39Sopenharmony_ci int xclass) 162e1051a39Sopenharmony_ci{ 163e1051a39Sopenharmony_ci unsigned char *p = *pp; 164e1051a39Sopenharmony_ci int i, ttag; 165e1051a39Sopenharmony_ci 166e1051a39Sopenharmony_ci i = (constructed) ? V_ASN1_CONSTRUCTED : 0; 167e1051a39Sopenharmony_ci i |= (xclass & V_ASN1_PRIVATE); 168e1051a39Sopenharmony_ci if (tag < 31) { 169e1051a39Sopenharmony_ci *(p++) = i | (tag & V_ASN1_PRIMITIVE_TAG); 170e1051a39Sopenharmony_ci } else { 171e1051a39Sopenharmony_ci *(p++) = i | V_ASN1_PRIMITIVE_TAG; 172e1051a39Sopenharmony_ci for (i = 0, ttag = tag; ttag > 0; i++) 173e1051a39Sopenharmony_ci ttag >>= 7; 174e1051a39Sopenharmony_ci ttag = i; 175e1051a39Sopenharmony_ci while (i-- > 0) { 176e1051a39Sopenharmony_ci p[i] = tag & 0x7f; 177e1051a39Sopenharmony_ci if (i != (ttag - 1)) 178e1051a39Sopenharmony_ci p[i] |= 0x80; 179e1051a39Sopenharmony_ci tag >>= 7; 180e1051a39Sopenharmony_ci } 181e1051a39Sopenharmony_ci p += ttag; 182e1051a39Sopenharmony_ci } 183e1051a39Sopenharmony_ci if (constructed == 2) 184e1051a39Sopenharmony_ci *(p++) = 0x80; 185e1051a39Sopenharmony_ci else 186e1051a39Sopenharmony_ci asn1_put_length(&p, length); 187e1051a39Sopenharmony_ci *pp = p; 188e1051a39Sopenharmony_ci} 189e1051a39Sopenharmony_ci 190e1051a39Sopenharmony_ciint ASN1_put_eoc(unsigned char **pp) 191e1051a39Sopenharmony_ci{ 192e1051a39Sopenharmony_ci unsigned char *p = *pp; 193e1051a39Sopenharmony_ci 194e1051a39Sopenharmony_ci *p++ = 0; 195e1051a39Sopenharmony_ci *p++ = 0; 196e1051a39Sopenharmony_ci *pp = p; 197e1051a39Sopenharmony_ci return 2; 198e1051a39Sopenharmony_ci} 199e1051a39Sopenharmony_ci 200e1051a39Sopenharmony_cistatic void asn1_put_length(unsigned char **pp, int length) 201e1051a39Sopenharmony_ci{ 202e1051a39Sopenharmony_ci unsigned char *p = *pp; 203e1051a39Sopenharmony_ci int i, len; 204e1051a39Sopenharmony_ci 205e1051a39Sopenharmony_ci if (length <= 127) { 206e1051a39Sopenharmony_ci *(p++) = (unsigned char)length; 207e1051a39Sopenharmony_ci } else { 208e1051a39Sopenharmony_ci len = length; 209e1051a39Sopenharmony_ci for (i = 0; len > 0; i++) 210e1051a39Sopenharmony_ci len >>= 8; 211e1051a39Sopenharmony_ci *(p++) = i | 0x80; 212e1051a39Sopenharmony_ci len = i; 213e1051a39Sopenharmony_ci while (i-- > 0) { 214e1051a39Sopenharmony_ci p[i] = length & 0xff; 215e1051a39Sopenharmony_ci length >>= 8; 216e1051a39Sopenharmony_ci } 217e1051a39Sopenharmony_ci p += len; 218e1051a39Sopenharmony_ci } 219e1051a39Sopenharmony_ci *pp = p; 220e1051a39Sopenharmony_ci} 221e1051a39Sopenharmony_ci 222e1051a39Sopenharmony_ciint ASN1_object_size(int constructed, int length, int tag) 223e1051a39Sopenharmony_ci{ 224e1051a39Sopenharmony_ci int ret = 1; 225e1051a39Sopenharmony_ci 226e1051a39Sopenharmony_ci if (length < 0) 227e1051a39Sopenharmony_ci return -1; 228e1051a39Sopenharmony_ci if (tag >= 31) { 229e1051a39Sopenharmony_ci while (tag > 0) { 230e1051a39Sopenharmony_ci tag >>= 7; 231e1051a39Sopenharmony_ci ret++; 232e1051a39Sopenharmony_ci } 233e1051a39Sopenharmony_ci } 234e1051a39Sopenharmony_ci if (constructed == 2) { 235e1051a39Sopenharmony_ci ret += 3; 236e1051a39Sopenharmony_ci } else { 237e1051a39Sopenharmony_ci ret++; 238e1051a39Sopenharmony_ci if (length > 127) { 239e1051a39Sopenharmony_ci int tmplen = length; 240e1051a39Sopenharmony_ci while (tmplen > 0) { 241e1051a39Sopenharmony_ci tmplen >>= 8; 242e1051a39Sopenharmony_ci ret++; 243e1051a39Sopenharmony_ci } 244e1051a39Sopenharmony_ci } 245e1051a39Sopenharmony_ci } 246e1051a39Sopenharmony_ci if (ret >= INT_MAX - length) 247e1051a39Sopenharmony_ci return -1; 248e1051a39Sopenharmony_ci return ret + length; 249e1051a39Sopenharmony_ci} 250e1051a39Sopenharmony_ci 251e1051a39Sopenharmony_ciint ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str) 252e1051a39Sopenharmony_ci{ 253e1051a39Sopenharmony_ci if (str == NULL) 254e1051a39Sopenharmony_ci return 0; 255e1051a39Sopenharmony_ci dst->type = str->type; 256e1051a39Sopenharmony_ci if (!ASN1_STRING_set(dst, str->data, str->length)) 257e1051a39Sopenharmony_ci return 0; 258e1051a39Sopenharmony_ci /* Copy flags but preserve embed value */ 259e1051a39Sopenharmony_ci dst->flags &= ASN1_STRING_FLAG_EMBED; 260e1051a39Sopenharmony_ci dst->flags |= str->flags & ~ASN1_STRING_FLAG_EMBED; 261e1051a39Sopenharmony_ci return 1; 262e1051a39Sopenharmony_ci} 263e1051a39Sopenharmony_ci 264e1051a39Sopenharmony_ciASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *str) 265e1051a39Sopenharmony_ci{ 266e1051a39Sopenharmony_ci ASN1_STRING *ret; 267e1051a39Sopenharmony_ci 268e1051a39Sopenharmony_ci if (!str) 269e1051a39Sopenharmony_ci return NULL; 270e1051a39Sopenharmony_ci ret = ASN1_STRING_new(); 271e1051a39Sopenharmony_ci if (ret == NULL) 272e1051a39Sopenharmony_ci return NULL; 273e1051a39Sopenharmony_ci if (!ASN1_STRING_copy(ret, str)) { 274e1051a39Sopenharmony_ci ASN1_STRING_free(ret); 275e1051a39Sopenharmony_ci return NULL; 276e1051a39Sopenharmony_ci } 277e1051a39Sopenharmony_ci return ret; 278e1051a39Sopenharmony_ci} 279e1051a39Sopenharmony_ci 280e1051a39Sopenharmony_ciint ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len_in) 281e1051a39Sopenharmony_ci{ 282e1051a39Sopenharmony_ci unsigned char *c; 283e1051a39Sopenharmony_ci const char *data = _data; 284e1051a39Sopenharmony_ci size_t len; 285e1051a39Sopenharmony_ci 286e1051a39Sopenharmony_ci if (len_in < 0) { 287e1051a39Sopenharmony_ci if (data == NULL) 288e1051a39Sopenharmony_ci return 0; 289e1051a39Sopenharmony_ci len = strlen(data); 290e1051a39Sopenharmony_ci } else { 291e1051a39Sopenharmony_ci len = (size_t)len_in; 292e1051a39Sopenharmony_ci } 293e1051a39Sopenharmony_ci /* 294e1051a39Sopenharmony_ci * Verify that the length fits within an integer for assignment to 295e1051a39Sopenharmony_ci * str->length below. The additional 1 is subtracted to allow for the 296e1051a39Sopenharmony_ci * '\0' terminator even though this isn't strictly necessary. 297e1051a39Sopenharmony_ci */ 298e1051a39Sopenharmony_ci if (len > INT_MAX - 1) { 299e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_LARGE); 300e1051a39Sopenharmony_ci return 0; 301e1051a39Sopenharmony_ci } 302e1051a39Sopenharmony_ci if ((size_t)str->length <= len || str->data == NULL) { 303e1051a39Sopenharmony_ci c = str->data; 304e1051a39Sopenharmony_ci#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION 305e1051a39Sopenharmony_ci /* No NUL terminator in fuzzing builds */ 306e1051a39Sopenharmony_ci str->data = OPENSSL_realloc(c, len != 0 ? len : 1); 307e1051a39Sopenharmony_ci#else 308e1051a39Sopenharmony_ci str->data = OPENSSL_realloc(c, len + 1); 309e1051a39Sopenharmony_ci#endif 310e1051a39Sopenharmony_ci if (str->data == NULL) { 311e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); 312e1051a39Sopenharmony_ci str->data = c; 313e1051a39Sopenharmony_ci return 0; 314e1051a39Sopenharmony_ci } 315e1051a39Sopenharmony_ci } 316e1051a39Sopenharmony_ci str->length = len; 317e1051a39Sopenharmony_ci if (data != NULL) { 318e1051a39Sopenharmony_ci memcpy(str->data, data, len); 319e1051a39Sopenharmony_ci#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION 320e1051a39Sopenharmony_ci /* Set the unused byte to something non NUL and printable. */ 321e1051a39Sopenharmony_ci if (len == 0) 322e1051a39Sopenharmony_ci str->data[len] = '~'; 323e1051a39Sopenharmony_ci#else 324e1051a39Sopenharmony_ci /* 325e1051a39Sopenharmony_ci * Add a NUL terminator. This should not be necessary - but we add it as 326e1051a39Sopenharmony_ci * a safety precaution 327e1051a39Sopenharmony_ci */ 328e1051a39Sopenharmony_ci str->data[len] = '\0'; 329e1051a39Sopenharmony_ci#endif 330e1051a39Sopenharmony_ci } 331e1051a39Sopenharmony_ci return 1; 332e1051a39Sopenharmony_ci} 333e1051a39Sopenharmony_ci 334e1051a39Sopenharmony_civoid ASN1_STRING_set0(ASN1_STRING *str, void *data, int len) 335e1051a39Sopenharmony_ci{ 336e1051a39Sopenharmony_ci OPENSSL_free(str->data); 337e1051a39Sopenharmony_ci str->data = data; 338e1051a39Sopenharmony_ci str->length = len; 339e1051a39Sopenharmony_ci} 340e1051a39Sopenharmony_ci 341e1051a39Sopenharmony_ciASN1_STRING *ASN1_STRING_new(void) 342e1051a39Sopenharmony_ci{ 343e1051a39Sopenharmony_ci return ASN1_STRING_type_new(V_ASN1_OCTET_STRING); 344e1051a39Sopenharmony_ci} 345e1051a39Sopenharmony_ci 346e1051a39Sopenharmony_ciASN1_STRING *ASN1_STRING_type_new(int type) 347e1051a39Sopenharmony_ci{ 348e1051a39Sopenharmony_ci ASN1_STRING *ret; 349e1051a39Sopenharmony_ci 350e1051a39Sopenharmony_ci ret = OPENSSL_zalloc(sizeof(*ret)); 351e1051a39Sopenharmony_ci if (ret == NULL) { 352e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); 353e1051a39Sopenharmony_ci return NULL; 354e1051a39Sopenharmony_ci } 355e1051a39Sopenharmony_ci ret->type = type; 356e1051a39Sopenharmony_ci return ret; 357e1051a39Sopenharmony_ci} 358e1051a39Sopenharmony_ci 359e1051a39Sopenharmony_civoid ossl_asn1_string_embed_free(ASN1_STRING *a, int embed) 360e1051a39Sopenharmony_ci{ 361e1051a39Sopenharmony_ci if (a == NULL) 362e1051a39Sopenharmony_ci return; 363e1051a39Sopenharmony_ci if (!(a->flags & ASN1_STRING_FLAG_NDEF)) 364e1051a39Sopenharmony_ci OPENSSL_free(a->data); 365e1051a39Sopenharmony_ci if (embed == 0) 366e1051a39Sopenharmony_ci OPENSSL_free(a); 367e1051a39Sopenharmony_ci} 368e1051a39Sopenharmony_ci 369e1051a39Sopenharmony_civoid ASN1_STRING_free(ASN1_STRING *a) 370e1051a39Sopenharmony_ci{ 371e1051a39Sopenharmony_ci if (a == NULL) 372e1051a39Sopenharmony_ci return; 373e1051a39Sopenharmony_ci ossl_asn1_string_embed_free(a, a->flags & ASN1_STRING_FLAG_EMBED); 374e1051a39Sopenharmony_ci} 375e1051a39Sopenharmony_ci 376e1051a39Sopenharmony_civoid ASN1_STRING_clear_free(ASN1_STRING *a) 377e1051a39Sopenharmony_ci{ 378e1051a39Sopenharmony_ci if (a == NULL) 379e1051a39Sopenharmony_ci return; 380e1051a39Sopenharmony_ci if (a->data && !(a->flags & ASN1_STRING_FLAG_NDEF)) 381e1051a39Sopenharmony_ci OPENSSL_cleanse(a->data, a->length); 382e1051a39Sopenharmony_ci ASN1_STRING_free(a); 383e1051a39Sopenharmony_ci} 384e1051a39Sopenharmony_ci 385e1051a39Sopenharmony_ciint ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b) 386e1051a39Sopenharmony_ci{ 387e1051a39Sopenharmony_ci int i; 388e1051a39Sopenharmony_ci 389e1051a39Sopenharmony_ci i = (a->length - b->length); 390e1051a39Sopenharmony_ci if (i == 0) { 391e1051a39Sopenharmony_ci if (a->length != 0) 392e1051a39Sopenharmony_ci i = memcmp(a->data, b->data, a->length); 393e1051a39Sopenharmony_ci if (i == 0) 394e1051a39Sopenharmony_ci return a->type - b->type; 395e1051a39Sopenharmony_ci else 396e1051a39Sopenharmony_ci return i; 397e1051a39Sopenharmony_ci } else { 398e1051a39Sopenharmony_ci return i; 399e1051a39Sopenharmony_ci } 400e1051a39Sopenharmony_ci} 401e1051a39Sopenharmony_ci 402e1051a39Sopenharmony_ciint ASN1_STRING_length(const ASN1_STRING *x) 403e1051a39Sopenharmony_ci{ 404e1051a39Sopenharmony_ci return x->length; 405e1051a39Sopenharmony_ci} 406e1051a39Sopenharmony_ci 407e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_DEPRECATED_3_0 408e1051a39Sopenharmony_civoid ASN1_STRING_length_set(ASN1_STRING *x, int len) 409e1051a39Sopenharmony_ci{ 410e1051a39Sopenharmony_ci x->length = len; 411e1051a39Sopenharmony_ci} 412e1051a39Sopenharmony_ci#endif 413e1051a39Sopenharmony_ci 414e1051a39Sopenharmony_ciint ASN1_STRING_type(const ASN1_STRING *x) 415e1051a39Sopenharmony_ci{ 416e1051a39Sopenharmony_ci return x->type; 417e1051a39Sopenharmony_ci} 418e1051a39Sopenharmony_ci 419e1051a39Sopenharmony_ciconst unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *x) 420e1051a39Sopenharmony_ci{ 421e1051a39Sopenharmony_ci return x->data; 422e1051a39Sopenharmony_ci} 423e1051a39Sopenharmony_ci 424e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_DEPRECATED_1_1_0 425e1051a39Sopenharmony_ciunsigned char *ASN1_STRING_data(ASN1_STRING *x) 426e1051a39Sopenharmony_ci{ 427e1051a39Sopenharmony_ci return x->data; 428e1051a39Sopenharmony_ci} 429e1051a39Sopenharmony_ci#endif 430e1051a39Sopenharmony_ci 431e1051a39Sopenharmony_ci/* |max_len| excludes NUL terminator and may be 0 to indicate no restriction */ 432e1051a39Sopenharmony_cichar *ossl_sk_ASN1_UTF8STRING2text(STACK_OF(ASN1_UTF8STRING) *text, 433e1051a39Sopenharmony_ci const char *sep, size_t max_len) 434e1051a39Sopenharmony_ci{ 435e1051a39Sopenharmony_ci int i; 436e1051a39Sopenharmony_ci ASN1_UTF8STRING *current; 437e1051a39Sopenharmony_ci size_t length = 0, sep_len; 438e1051a39Sopenharmony_ci char *result = NULL; 439e1051a39Sopenharmony_ci char *p; 440e1051a39Sopenharmony_ci 441e1051a39Sopenharmony_ci if (sep == NULL) 442e1051a39Sopenharmony_ci sep = ""; 443e1051a39Sopenharmony_ci sep_len = strlen(sep); 444e1051a39Sopenharmony_ci 445e1051a39Sopenharmony_ci for (i = 0; i < sk_ASN1_UTF8STRING_num(text); i++) { 446e1051a39Sopenharmony_ci current = sk_ASN1_UTF8STRING_value(text, i); 447e1051a39Sopenharmony_ci if (i > 0) 448e1051a39Sopenharmony_ci length += sep_len; 449e1051a39Sopenharmony_ci length += ASN1_STRING_length(current); 450e1051a39Sopenharmony_ci if (max_len != 0 && length > max_len) 451e1051a39Sopenharmony_ci return NULL; 452e1051a39Sopenharmony_ci } 453e1051a39Sopenharmony_ci if ((result = OPENSSL_malloc(length + 1)) == NULL) 454e1051a39Sopenharmony_ci return NULL; 455e1051a39Sopenharmony_ci 456e1051a39Sopenharmony_ci p = result; 457e1051a39Sopenharmony_ci for (i = 0; i < sk_ASN1_UTF8STRING_num(text); i++) { 458e1051a39Sopenharmony_ci current = sk_ASN1_UTF8STRING_value(text, i); 459e1051a39Sopenharmony_ci length = ASN1_STRING_length(current); 460e1051a39Sopenharmony_ci if (i > 0 && sep_len > 0) { 461e1051a39Sopenharmony_ci strncpy(p, sep, sep_len + 1); /* using + 1 to silence gcc warning */ 462e1051a39Sopenharmony_ci p += sep_len; 463e1051a39Sopenharmony_ci } 464e1051a39Sopenharmony_ci strncpy(p, (const char *)ASN1_STRING_get0_data(current), length); 465e1051a39Sopenharmony_ci p += length; 466e1051a39Sopenharmony_ci } 467e1051a39Sopenharmony_ci *p = '\0'; 468e1051a39Sopenharmony_ci 469e1051a39Sopenharmony_ci return result; 470e1051a39Sopenharmony_ci} 471