195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * All rights reserved. 395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * This package is an SSL implementation written 595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * by Eric Young (eay@cryptsoft.com). 695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * The implementation was written so as to conform with Netscapes SSL. 795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * This library is free for commercial and non-commercial use as long as 995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * the following conditions are aheared to. The following conditions 1095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * apply to all code found in this distribution, be it the RC4, RSA, 1195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * included with this distribution is covered by the same copyright terms 1395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * except that the holder is Tim Hudson (tjh@cryptsoft.com). 1495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 1595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Copyright remains Eric Young's, and as such any Copyright notices in 1695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * the code are not to be removed. 1795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * If this package is used in a product, Eric Young should be given attribution 1895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * as the author of the parts of the library used. 1995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * This can be in the form of a textual message at program startup or 2095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * in documentation (online or textual) provided with the package. 2195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 2295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Redistribution and use in source and binary forms, with or without 2395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * modification, are permitted provided that the following conditions 2495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * are met: 2595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 1. Redistributions of source code must retain the copyright 2695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * notice, this list of conditions and the following disclaimer. 2795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 2. Redistributions in binary form must reproduce the above copyright 2895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * notice, this list of conditions and the following disclaimer in the 2995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * documentation and/or other materials provided with the distribution. 3095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 3. All advertising materials mentioning features or use of this software 3195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * must display the following acknowledgement: 3295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * "This product includes cryptographic software written by 3395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Eric Young (eay@cryptsoft.com)" 3495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * The word 'cryptographic' can be left out if the rouines from the library 3595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * being used are not cryptographic related :-). 3695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 4. If you include any Windows specific code (or a derivative thereof) from 3795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * the apps directory (application code) you must include an acknowledgement: 3895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 3995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 4095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 4995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * SUCH DAMAGE. 5195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 5295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * The licence and distribution terms for any publically available version or 5395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * derivative of this code cannot be changed. i.e. this code cannot simply be 5495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * copied and put under another distribution licence 5595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * [including the GNU Public Licence.] */ 5695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 5795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/obj.h> 5895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 5995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <limits.h> 6095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 6195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/asn1.h> 6295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/buf.h> 6395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/bytestring.h> 6495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/err.h> 6595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/lhash.h> 6695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/mem.h> 6795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/thread.h> 6895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 698a5825e4c7238eef74f8a7ad5b054914e16899cbDavid Benjamin#include "obj_dat.h" 7095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 7195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* These globals are protected by CRYPTO_LOCK_OBJ. */ 7295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic LHASH_OF(ASN1_OBJECT) *global_added_by_data = NULL; 7395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic LHASH_OF(ASN1_OBJECT) *global_added_by_nid = NULL; 7495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic LHASH_OF(ASN1_OBJECT) *global_added_by_short_name = NULL; 7595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic LHASH_OF(ASN1_OBJECT) *global_added_by_long_name = NULL; 7695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 7795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic unsigned global_next_nid = NUM_NID; 7895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 79c44d2f4cb8a892a603edbbe710fa82bcd30f9cb5David Benjaminstatic int obj_next_nid(void) { 8095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int ret; 8195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 8295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_w_lock(CRYPTO_LOCK_OBJ); 8395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ret = global_next_nid++; 8495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_w_unlock(CRYPTO_LOCK_OBJ); 8595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 8695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return ret; 8795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 8895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 8995c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o) { 9095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_OBJECT *r; 9195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley unsigned char *data = NULL; 9295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley char *sn = NULL, *ln = NULL; 9395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 9495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (o == NULL) { 9595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return NULL; 9695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 9795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 9895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!(o->flags & ASN1_OBJECT_FLAG_DYNAMIC)) { 9995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* TODO(fork): this is a little dangerous. */ 10095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return (ASN1_OBJECT *)o; 10195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 10295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 10395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley r = ASN1_OBJECT_new(); 10495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (r == NULL) { 10595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(OBJ, OBJ_dup, ERR_R_ASN1_LIB); 10695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return NULL; 10795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 10895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley r->ln = r->sn = NULL; 10995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 11095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley data = OPENSSL_malloc(o->length); 11195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (data == NULL) { 11295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 11395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 11495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (o->data != NULL) { 11595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley memcpy(data, o->data, o->length); 11695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 11795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 11895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* once data is attached to an object, it remains const */ 11995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley r->data = data; 12095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley r->length = o->length; 12195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley r->nid = o->nid; 12295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 12395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (o->ln != NULL) { 12495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ln = OPENSSL_strdup(o->ln); 12595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ln == NULL) { 12695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 12795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 12895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 12995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 13095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (o->sn != NULL) { 13195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley sn = OPENSSL_strdup(o->sn); 13295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (sn) { 13395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 13495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 13595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 13695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 13795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley r->sn = sn; 13895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley r->ln = ln; 13995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 14095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley r->flags = 14195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley o->flags | (ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | 14295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_OBJECT_FLAG_DYNAMIC_DATA); 14395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return r; 14495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 14595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyerr: 14695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(OBJ, OBJ_dup, ERR_R_MALLOC_FAILURE); 14795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ln != NULL) { 14895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_free(ln); 14995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 15095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (sn != NULL) { 15195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_free(sn); 15295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 15395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (data != NULL) { 15495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_free(data); 15595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 15695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_free(r); 15795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return NULL; 15895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 15995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 16095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint OBJ_cmp(const ASN1_OBJECT *a, const ASN1_OBJECT *b) { 16195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int ret; 16295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 16395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ret = a->length - b->length; 16495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ret) { 16595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return ret; 16695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 16795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return memcmp(a->data, b->data, a->length); 16895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 16995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 17095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* nids_cmp is called to search the kNIDsInOIDOrder array. The |key| argument 17195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * is an |ASN1_OBJECT|* that we're looking for and |element| is a pointer to an 17295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * unsigned int in the array. */ 17395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int obj_cmp(const void *key, const void *element) { 17495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int j; 17595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley unsigned nid = *((unsigned*) element); 17695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const ASN1_OBJECT *a = key; 17795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const ASN1_OBJECT *b = &kObjects[nid]; 17895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 17995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley j = a->length - b->length; 18095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (j) { 18195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return j; 18295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 18395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return memcmp(a->data, b->data, a->length); 18495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 18595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 18695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint OBJ_obj2nid(const ASN1_OBJECT *obj) { 18795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const unsigned int *nid_ptr; 18895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 18995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (obj == NULL) { 19095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return NID_undef; 19195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 19295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 19395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (obj->nid != 0) { 19495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return obj->nid; 19595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 19695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 19795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_r_lock(CRYPTO_LOCK_OBJ); 19895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (global_added_by_data != NULL) { 19995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_OBJECT *match; 20095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 20195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley match = lh_ASN1_OBJECT_retrieve(global_added_by_data, obj); 20295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (match != NULL) { 20395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_r_unlock(CRYPTO_LOCK_OBJ); 20495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return match->nid; 20595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 20695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 20795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_r_unlock(CRYPTO_LOCK_OBJ); 20895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 20995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley nid_ptr = bsearch(obj, kNIDsInOIDOrder, NUM_OBJ, sizeof(unsigned), obj_cmp); 21095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (nid_ptr == NULL) { 21195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return NID_undef; 21295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 21395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 21495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return kObjects[*nid_ptr].nid; 21595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 21695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 21795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint OBJ_cbs2nid(const CBS *cbs) { 21895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_OBJECT obj; 21995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley memset(&obj, 0, sizeof(obj)); 22095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley obj.data = CBS_data(cbs); 22195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley obj.length = CBS_len(cbs); 22295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 22395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return OBJ_obj2nid(&obj); 22495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 22595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 22695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* short_name_cmp is called to search the kNIDsInShortNameOrder array. The 22795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * |key| argument is name that we're looking for and |element| is a pointer to 22895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * an unsigned int in the array. */ 22995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int short_name_cmp(const void *key, const void *element) { 23095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const char *name = (const char *) key; 23195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley unsigned nid = *((unsigned*) element); 23295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 23395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return strcmp(name, kObjects[nid].sn); 23495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 23595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 23695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint OBJ_sn2nid(const char *short_name) { 23795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const unsigned int *nid_ptr; 23895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 23995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_r_lock(CRYPTO_LOCK_OBJ); 24095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (global_added_by_short_name != NULL) { 24195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_OBJECT *match, template; 24295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 24395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley template.sn = short_name; 24495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley match = lh_ASN1_OBJECT_retrieve(global_added_by_short_name, &template); 24595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (match != NULL) { 24695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_r_unlock(CRYPTO_LOCK_OBJ); 24795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return match->nid; 24895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 24995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 25095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_r_unlock(CRYPTO_LOCK_OBJ); 25195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 25295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley nid_ptr = bsearch(short_name, kNIDsInShortNameOrder, NUM_SN, sizeof(unsigned), short_name_cmp); 25395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (nid_ptr == NULL) { 25495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return NID_undef; 25595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 25695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 25795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return kObjects[*nid_ptr].nid; 25895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 25995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 26095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* long_name_cmp is called to search the kNIDsInLongNameOrder array. The 26195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * |key| argument is name that we're looking for and |element| is a pointer to 26295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * an unsigned int in the array. */ 26395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int long_name_cmp(const void *key, const void *element) { 26495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const char *name = (const char *) key; 26595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley unsigned nid = *((unsigned*) element); 26695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 26795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return strcmp(name, kObjects[nid].ln); 26895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 26995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 27095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint OBJ_ln2nid(const char *long_name) { 27195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const unsigned int *nid_ptr; 27295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 27395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_r_lock(CRYPTO_LOCK_OBJ); 27495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (global_added_by_long_name != NULL) { 27595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_OBJECT *match, template; 27695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 27795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley template.ln = long_name; 27895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley match = lh_ASN1_OBJECT_retrieve(global_added_by_long_name, &template); 27995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (match != NULL) { 28095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_r_unlock(CRYPTO_LOCK_OBJ); 28195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return match->nid; 28295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 28395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 28495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_r_unlock(CRYPTO_LOCK_OBJ); 28595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 28695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley nid_ptr = bsearch(long_name, kNIDsInLongNameOrder, NUM_LN, sizeof(unsigned), long_name_cmp); 28795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (nid_ptr == NULL) { 28895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return NID_undef; 28995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 29095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 29195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return kObjects[*nid_ptr].nid; 29295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 29395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 29495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint OBJ_txt2nid(const char *s) { 29595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_OBJECT *obj; 29695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int nid; 29795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 29895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley obj = OBJ_txt2obj(s, 0 /* search names */); 29995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley nid = OBJ_obj2nid(obj); 30095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_OBJECT_free(obj); 30195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return nid; 30295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 30395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 304eeb9f491e8f07a3160df6c586a5bde42ebceb672Adam LangleyOPENSSL_EXPORT int OBJ_nid2cbb(CBB *out, int nid) { 305eeb9f491e8f07a3160df6c586a5bde42ebceb672Adam Langley const ASN1_OBJECT *obj = OBJ_nid2obj(nid); 306eeb9f491e8f07a3160df6c586a5bde42ebceb672Adam Langley CBB oid; 307eeb9f491e8f07a3160df6c586a5bde42ebceb672Adam Langley 308eeb9f491e8f07a3160df6c586a5bde42ebceb672Adam Langley if (obj == NULL || 309eeb9f491e8f07a3160df6c586a5bde42ebceb672Adam Langley !CBB_add_asn1(out, &oid, CBS_ASN1_OBJECT) || 310eeb9f491e8f07a3160df6c586a5bde42ebceb672Adam Langley !CBB_add_bytes(&oid, obj->data, obj->length) || 311eeb9f491e8f07a3160df6c586a5bde42ebceb672Adam Langley !CBB_flush(out)) { 312eeb9f491e8f07a3160df6c586a5bde42ebceb672Adam Langley return 0; 313eeb9f491e8f07a3160df6c586a5bde42ebceb672Adam Langley } 314eeb9f491e8f07a3160df6c586a5bde42ebceb672Adam Langley 315eeb9f491e8f07a3160df6c586a5bde42ebceb672Adam Langley return 1; 316eeb9f491e8f07a3160df6c586a5bde42ebceb672Adam Langley} 317eeb9f491e8f07a3160df6c586a5bde42ebceb672Adam Langley 31895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyconst ASN1_OBJECT *OBJ_nid2obj(int nid) { 31995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (nid >= 0 && nid < NUM_NID) { 32095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (nid != NID_undef && kObjects[nid].nid == NID_undef) { 32195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 32295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 32395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return &kObjects[nid]; 32495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 32595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 32695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_r_lock(CRYPTO_LOCK_OBJ); 32795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (global_added_by_nid != NULL) { 32895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_OBJECT *match, template; 32995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 33095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley template.nid = nid; 33195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley match = lh_ASN1_OBJECT_retrieve(global_added_by_nid, &template); 33295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (match != NULL) { 33395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_r_unlock(CRYPTO_LOCK_OBJ); 33495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return match; 33595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 33695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 33795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_r_unlock(CRYPTO_LOCK_OBJ); 33895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 33995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyerr: 34095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(OBJ, OBJ_nid2obj, OBJ_R_UNKNOWN_NID); 34195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return NULL; 34295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 34395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 34495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyconst char *OBJ_nid2sn(int nid) { 34595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const ASN1_OBJECT *obj = OBJ_nid2obj(nid); 34695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (obj == NULL) { 34795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return NULL; 34895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 34995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 35095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return obj->sn; 35195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 35295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 35395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyconst char *OBJ_nid2ln(int nid) { 35495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const ASN1_OBJECT *obj = OBJ_nid2obj(nid); 35595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (obj == NULL) { 35695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return NULL; 35795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 35895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 35995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return obj->ln; 36095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 36195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 36295c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyASN1_OBJECT *OBJ_txt2obj(const char *s, int dont_search_names) { 36395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int nid = NID_undef; 36495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_OBJECT *op = NULL; 36595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley unsigned char *buf; 36695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley unsigned char *p; 36795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const unsigned char *bufp; 36895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int contents_len, total_len; 36995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 37095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!dont_search_names) { 37195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley nid = OBJ_sn2nid(s); 37295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (nid == NID_undef) { 37395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley nid = OBJ_ln2nid(s); 37495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 37595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 37695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (nid != NID_undef) { 37795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return (ASN1_OBJECT*) OBJ_nid2obj(nid); 37895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 37995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 38095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 38195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Work out size of content octets */ 38295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley contents_len = a2d_ASN1_OBJECT(NULL, 0, s, -1); 38395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (contents_len <= 0) { 38495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return NULL; 38595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 38695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Work out total size */ 38795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley total_len = ASN1_object_size(0, contents_len, V_ASN1_OBJECT); 38895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 38995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley buf = OPENSSL_malloc(total_len); 39095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (buf == NULL) { 39195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(OBJ, OBJ_txt2obj, ERR_R_MALLOC_FAILURE); 39295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return NULL; 39395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 39495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 39595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley p = buf; 39695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Write out tag+length */ 39795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_put_object(&p, 0, contents_len, V_ASN1_OBJECT, V_ASN1_UNIVERSAL); 39895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Write out contents */ 39995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley a2d_ASN1_OBJECT(p, contents_len, s, -1); 40095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 40195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley bufp = buf; 40295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley op = d2i_ASN1_OBJECT(NULL, &bufp, total_len); 40395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_free(buf); 40495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 40595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return op; 40695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 40795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 40895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint OBJ_obj2txt(char *out, int out_len, const ASN1_OBJECT *obj, int dont_return_name) { 40995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int i, n = 0, len, nid, first, use_bn; 41095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley BIGNUM *bl; 41195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley unsigned long l; 41295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const unsigned char *p; 41395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley char tbuf[DECIMAL_SIZE(i) + DECIMAL_SIZE(l) + 2]; 41495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 41595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (out && out_len > 0) { 41695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley out[0] = 0; 41795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 41895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 41995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (obj == NULL || obj->data == NULL) { 42095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 42195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 42295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 42395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!dont_return_name && (nid = OBJ_obj2nid(obj)) != NID_undef) { 42495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const char *s; 42595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley s = OBJ_nid2ln(nid); 42695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (s == NULL) { 42795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley s = OBJ_nid2sn(nid); 42895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 42995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (s) { 43095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (out) { 43195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley BUF_strlcpy(out, s, out_len); 43295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 43395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return strlen(s); 43495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 43595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 43695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 43795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley len = obj->length; 43895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley p = obj->data; 43995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 44095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley first = 1; 44195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley bl = NULL; 44295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 44395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley while (len > 0) { 44495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley l = 0; 44595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley use_bn = 0; 44695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for (;;) { 44795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley unsigned char c = *p++; 44895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley len--; 44995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (len == 0 && (c & 0x80)) { 45095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 45195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 45295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (use_bn) { 45395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!BN_add_word(bl, c & 0x7f)) { 45495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 45595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 45695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } else { 45795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley l |= c & 0x7f; 45895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 45995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!(c & 0x80)) { 46095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley break; 46195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 46295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!use_bn && (l > (ULONG_MAX >> 7L))) { 46395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!bl && !(bl = BN_new())) { 46495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 46595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 46695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!BN_set_word(bl, l)) { 46795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 46895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 46995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley use_bn = 1; 47095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 47195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (use_bn) { 47295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!BN_lshift(bl, bl, 7)) { 47395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 47495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 47595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } else { 47695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley l <<= 7L; 47795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 47895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 47995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 48095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (first) { 48195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley first = 0; 48295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (l >= 80) { 48395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley i = 2; 48495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (use_bn) { 48595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!BN_sub_word(bl, 80)) { 48695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 48795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 48895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } else { 48995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley l -= 80; 49095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 49195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } else { 49295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley i = (int)(l / 40); 49395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley l -= (long)(i * 40); 49495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 49595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (out && out_len > 1) { 49695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *out++ = i + '0'; 49795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *out = '0'; 49895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley out_len--; 49995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 50095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley n++; 50195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 50295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 50395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (use_bn) { 50495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley char *bndec; 50595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley bndec = BN_bn2dec(bl); 50695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!bndec) { 50795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 50895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 50995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley i = strlen(bndec); 51095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (out) { 51195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (out_len > 1) { 51295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *out++ = '.'; 51395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *out = 0; 51495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley out_len--; 51595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 51695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley BUF_strlcpy(out, bndec, out_len); 51795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (i > out_len) { 51895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley out += out_len; 51995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley out_len = 0; 52095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } else { 52195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley out += i; 52295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley out_len -= i; 52395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 52495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 52595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley n++; 52695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley n += i; 52795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_free(bndec); 52895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } else { 52995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley BIO_snprintf(tbuf, sizeof(tbuf), ".%lu", l); 53095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley i = strlen(tbuf); 53195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (out && out_len > 0) { 53295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley BUF_strlcpy(out, tbuf, out_len); 53395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (i > out_len) { 53495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley out += out_len; 53595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley out_len = 0; 53695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } else { 53795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley out += i; 53895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley out_len -= i; 53995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 54095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 54195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley n += i; 54295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 54395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 54495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 54595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (bl) { 54695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley BN_free(bl); 54795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 54895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return n; 54995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 55095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyerr: 55195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (bl) { 55295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley BN_free(bl); 55395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 55495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return -1; 55595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 55695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 55795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic uint32_t hash_nid(const ASN1_OBJECT *obj) { 55895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return obj->nid; 55995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 56095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 56195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int cmp_nid(const ASN1_OBJECT *a, const ASN1_OBJECT *b) { 56295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return a->nid - b->nid; 56395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 56495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 56595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic uint32_t hash_data(const ASN1_OBJECT *obj) { 56695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return OPENSSL_hash32(obj->data, obj->length); 56795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 56895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 56995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int cmp_data(const ASN1_OBJECT *a, const ASN1_OBJECT *b) { 57095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int i = a->length - b->length; 57195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (i) { 57295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return i; 57395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 57495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return memcmp(a->data, b->data, a->length); 57595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 57695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 57795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic uint32_t hash_short_name(const ASN1_OBJECT *obj) { 57895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return lh_strhash(obj->sn); 57995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 58095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 58195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int cmp_short_name(const ASN1_OBJECT *a, const ASN1_OBJECT *b) { 58295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return strcmp(a->sn, b->sn); 58395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 58495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 58595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic uint32_t hash_long_name(const ASN1_OBJECT *obj) { 58695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return lh_strhash(obj->ln); 58795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 58895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 58995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int cmp_long_name(const ASN1_OBJECT *a, const ASN1_OBJECT *b) { 59095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return strcmp(a->ln, b->ln); 59195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 59295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 59395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* obj_add_object inserts |obj| into the various global hashes for run-time 59495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * added objects. It returns one on success or zero otherwise. */ 59595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int obj_add_object(ASN1_OBJECT *obj) { 59695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int ok; 59795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_OBJECT *old_object; 59895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 59995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley obj->flags &= ~(ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | 60095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_OBJECT_FLAG_DYNAMIC_DATA); 60195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 60295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_w_lock(CRYPTO_LOCK_OBJ); 60395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (global_added_by_nid == NULL) { 60495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley global_added_by_nid = lh_ASN1_OBJECT_new(hash_nid, cmp_nid); 60595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley global_added_by_data = lh_ASN1_OBJECT_new(hash_data, cmp_data); 60695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley global_added_by_short_name = lh_ASN1_OBJECT_new(hash_short_name, cmp_short_name); 60795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley global_added_by_long_name = lh_ASN1_OBJECT_new(hash_long_name, cmp_long_name); 60895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 60995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 61095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* We don't pay attention to |old_object| (which contains any previous object 61195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * that was evicted from the hashes) because we don't have a reference count 61295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * on ASN1_OBJECT values. Also, we should never have duplicates nids and so 61395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * should always have objects in |global_added_by_nid|. */ 61495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 61595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ok = lh_ASN1_OBJECT_insert(global_added_by_nid, &old_object, obj); 61695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (obj->length != 0 && obj->data != NULL) { 61795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ok &= lh_ASN1_OBJECT_insert(global_added_by_data, &old_object, obj); 61895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 61995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (obj->sn != NULL) { 62095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ok &= lh_ASN1_OBJECT_insert(global_added_by_short_name, &old_object, obj); 62195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 62295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (obj->ln != NULL) { 62395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ok &= lh_ASN1_OBJECT_insert(global_added_by_long_name, &old_object, obj); 62495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 62595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_w_unlock(CRYPTO_LOCK_OBJ); 62695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 62795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return ok; 62895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 62995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 63095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint OBJ_create(const char *oid, const char *short_name, const char *long_name) { 63195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int ret = NID_undef; 63295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_OBJECT *op = NULL; 63395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley unsigned char *buf = NULL; 63495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int len; 63595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 63695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley len = a2d_ASN1_OBJECT(NULL, 0, oid, -1); 63795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (len <= 0) { 63895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 63995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 64095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 64195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley buf = OPENSSL_malloc(len); 64295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (buf == NULL) { 64395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(OBJ, OBJ_create, ERR_R_MALLOC_FAILURE); 64495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 64595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 64695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 64795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley len = a2d_ASN1_OBJECT(buf, len, oid, -1); 64895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (len == 0) { 64995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 65095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 65195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 65295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley op = (ASN1_OBJECT *)ASN1_OBJECT_create(obj_next_nid(), buf, len, short_name, 65395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley long_name); 65495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (op == NULL) { 65595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 65695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 65795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 65895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (obj_add_object(op)) { 65995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ret = op->nid; 66095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 66195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley op = NULL; 66295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 66395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyerr: 66495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (op != NULL) { 66595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_OBJECT_free(op); 66695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 66795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (buf != NULL) { 66895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_free(buf); 66995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 67095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 67195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return ret; 67295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 673