X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fobjects%2Fobj_dat.c;h=ef2d1e0ddaf2c14bac67714a001158bd1705e015;hp=e7366af8dc10585f875194e031e38450e7344f2f;hb=387e5ac856454e81d82a4b83388994fecbfc229e;hpb=a00ae6c46e0d7907a7c9f9e85334e968aa5fd338 diff --git a/crypto/objects/obj_dat.c b/crypto/objects/obj_dat.c index e7366af8dc..ef2d1e0dda 100644 --- a/crypto/objects/obj_dat.c +++ b/crypto/objects/obj_dat.c @@ -1,69 +1,22 @@ -/* crypto/objects/obj_dat.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. +/* + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html */ #include -#include +#include "internal/ctype.h" #include -#include "cryptlib.h" +#include "internal/cryptlib.h" #include #include -#include +#include "internal/objects.h" #include +#include "internal/asn1_int.h" +#include "obj_lcl.h" /* obj_dat.h is generated from objects.h by obj_dat.pl */ #include "obj_dat.h" @@ -77,25 +30,24 @@ DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj); #define ADDED_LNAME 2 #define ADDED_NID 3 -typedef struct added_obj_st { +struct added_obj_st { int type; ASN1_OBJECT *obj; -} ADDED_OBJ; -DECLARE_LHASH_OF(ADDED_OBJ); +}; static int new_nid = NUM_NID; static LHASH_OF(ADDED_OBJ) *added = NULL; static int sn_cmp(const ASN1_OBJECT *const *a, const unsigned int *b) { - return (strcmp((*a)->sn, nid_objs[*b].sn)); + return strcmp((*a)->sn, nid_objs[*b].sn); } IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, sn); static int ln_cmp(const ASN1_OBJECT *const *a, const unsigned int *b) { - return (strcmp((*a)->ln, nid_objs[*b].ln)); + return strcmp((*a)->ln, nid_objs[*b].ln); } IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, ln); @@ -116,10 +68,10 @@ static unsigned long added_obj_hash(const ADDED_OBJ *ca) ret ^= p[i] << ((i * 3) % 24); break; case ADDED_SNAME: - ret = lh_strhash(a->sn); + ret = OPENSSL_LH_strhash(a->sn); break; case ADDED_LNAME: - ret = lh_strhash(a->ln); + ret = OPENSSL_LH_strhash(a->ln); break; case ADDED_NID: ret = a->nid; @@ -130,11 +82,9 @@ static unsigned long added_obj_hash(const ADDED_OBJ *ca) } ret &= 0x3fffffffL; ret |= ((unsigned long)ca->type) << 30L; - return (ret); + return ret; } -static IMPLEMENT_LHASH_HASH_FN(added_obj, ADDED_OBJ) - static int added_obj_cmp(const ADDED_OBJ *ca, const ADDED_OBJ *cb) { ASN1_OBJECT *a, *b; @@ -142,45 +92,43 @@ static int added_obj_cmp(const ADDED_OBJ *ca, const ADDED_OBJ *cb) i = ca->type - cb->type; if (i) - return (i); + return i; a = ca->obj; b = cb->obj; switch (ca->type) { case ADDED_DATA: i = (a->length - b->length); if (i) - return (i); - return (memcmp(a->data, b->data, (size_t)a->length)); + return i; + return memcmp(a->data, b->data, (size_t)a->length); case ADDED_SNAME: if (a->sn == NULL) - return (-1); + return -1; else if (b->sn == NULL) - return (1); + return 1; else - return (strcmp(a->sn, b->sn)); + return strcmp(a->sn, b->sn); case ADDED_LNAME: if (a->ln == NULL) - return (-1); + return -1; else if (b->ln == NULL) - return (1); + return 1; else - return (strcmp(a->ln, b->ln)); + return strcmp(a->ln, b->ln); case ADDED_NID: - return (a->nid - b->nid); + return a->nid - b->nid; default: /* abort(); */ return 0; } } -static IMPLEMENT_LHASH_COMP_FN(added_obj, ADDED_OBJ) - static int init_added(void) { if (added != NULL) - return (1); - added = lh_ADDED_OBJ_new(); - return (added != NULL); + return 1; + added = lh_ADDED_OBJ_new(added_obj_hash, added_obj_cmp); + return added != NULL; } static void cleanup1_doall(ADDED_OBJ *a) @@ -202,34 +150,14 @@ static void cleanup3_doall(ADDED_OBJ *a) OPENSSL_free(a); } -static IMPLEMENT_LHASH_DOALL_FN(cleanup1, ADDED_OBJ) -static IMPLEMENT_LHASH_DOALL_FN(cleanup2, ADDED_OBJ) -static IMPLEMENT_LHASH_DOALL_FN(cleanup3, ADDED_OBJ) - -/* - * The purpose of obj_cleanup_defer is to avoid EVP_cleanup() attempting to - * use freed up OIDs. If necessary the actual freeing up of OIDs is delayed. - */ -int obj_cleanup_defer = 0; - -void check_defer(int nid) -{ - if (!obj_cleanup_defer && nid >= NUM_NID) - obj_cleanup_defer = 1; -} - -void OBJ_cleanup(void) +void obj_cleanup_int(void) { - if (obj_cleanup_defer) { - obj_cleanup_defer = 2; - return; - } if (added == NULL) return; - lh_ADDED_OBJ_down_load(added) = 0; - lh_ADDED_OBJ_doall(added, LHASH_DOALL_FN(cleanup1)); /* zero counters */ - lh_ADDED_OBJ_doall(added, LHASH_DOALL_FN(cleanup2)); /* set counters */ - lh_ADDED_OBJ_doall(added, LHASH_DOALL_FN(cleanup3)); /* free objects */ + lh_ADDED_OBJ_set_down_load(added, 0); + lh_ADDED_OBJ_doall(added, cleanup1_doall); /* zero counters */ + lh_ADDED_OBJ_doall(added, cleanup2_doall); /* set counters */ + lh_ADDED_OBJ_doall(added, cleanup3_doall); /* free objects */ lh_ADDED_OBJ_free(added); added = NULL; } @@ -240,7 +168,7 @@ int OBJ_new_nid(int num) i = new_nid; new_nid += num; - return (i); + return i; } int OBJ_add_object(const ASN1_OBJECT *obj) @@ -251,24 +179,19 @@ int OBJ_add_object(const ASN1_OBJECT *obj) if (added == NULL) if (!init_added()) - return (0); + return 0; if ((o = OBJ_dup(obj)) == NULL) goto err; - if (!(ao[ADDED_NID] = (ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)))) + if ((ao[ADDED_NID] = OPENSSL_malloc(sizeof(*ao[0]))) == NULL) goto err2; if ((o->length != 0) && (obj->data != NULL)) - if (! - (ao[ADDED_DATA] = (ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)))) + if ((ao[ADDED_DATA] = OPENSSL_malloc(sizeof(*ao[0]))) == NULL) goto err2; if (o->sn != NULL) - if (! - (ao[ADDED_SNAME] = - (ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)))) + if ((ao[ADDED_SNAME] = OPENSSL_malloc(sizeof(*ao[0]))) == NULL) goto err2; if (o->ln != NULL) - if (! - (ao[ADDED_LNAME] = - (ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)))) + if ((ao[ADDED_LNAME] = OPENSSL_malloc(sizeof(*ao[0]))) == NULL) goto err2; for (i = ADDED_DATA; i <= ADDED_NID; i++) { @@ -276,25 +199,22 @@ int OBJ_add_object(const ASN1_OBJECT *obj) ao[i]->type = i; ao[i]->obj = o; aop = lh_ADDED_OBJ_insert(added, ao[i]); - /* memory leak, buit should not normally matter */ - if (aop != NULL) - OPENSSL_free(aop); + /* memory leak, but should not normally matter */ + OPENSSL_free(aop); } } o->flags &= ~(ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | ASN1_OBJECT_FLAG_DYNAMIC_DATA); - return (o->nid); + return o->nid; err2: OBJerr(OBJ_F_OBJ_ADD_OBJECT, ERR_R_MALLOC_FAILURE); err: for (i = ADDED_DATA; i <= ADDED_NID; i++) - if (ao[i] != NULL) - OPENSSL_free(ao[i]); - if (o != NULL) - OPENSSL_free(o); - return (NID_undef); + OPENSSL_free(ao[i]); + ASN1_OBJECT_free(o); + return NID_undef; } ASN1_OBJECT *OBJ_nid2obj(int n) @@ -305,21 +225,21 @@ ASN1_OBJECT *OBJ_nid2obj(int n) if ((n >= 0) && (n < NUM_NID)) { if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) { OBJerr(OBJ_F_OBJ_NID2OBJ, OBJ_R_UNKNOWN_NID); - return (NULL); + return NULL; } - return ((ASN1_OBJECT *)&(nid_objs[n])); + return (ASN1_OBJECT *)&(nid_objs[n]); } else if (added == NULL) - return (NULL); + return NULL; else { ad.type = ADDED_NID; ad.obj = &ob; ob.nid = n; adp = lh_ADDED_OBJ_retrieve(added, &ad); if (adp != NULL) - return (adp->obj); + return adp->obj; else { OBJerr(OBJ_F_OBJ_NID2OBJ, OBJ_R_UNKNOWN_NID); - return (NULL); + return NULL; } } } @@ -332,21 +252,21 @@ const char *OBJ_nid2sn(int n) if ((n >= 0) && (n < NUM_NID)) { if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) { OBJerr(OBJ_F_OBJ_NID2SN, OBJ_R_UNKNOWN_NID); - return (NULL); + return NULL; } - return (nid_objs[n].sn); + return nid_objs[n].sn; } else if (added == NULL) - return (NULL); + return NULL; else { ad.type = ADDED_NID; ad.obj = &ob; ob.nid = n; adp = lh_ADDED_OBJ_retrieve(added, &ad); if (adp != NULL) - return (adp->obj->sn); + return adp->obj->sn; else { OBJerr(OBJ_F_OBJ_NID2SN, OBJ_R_UNKNOWN_NID); - return (NULL); + return NULL; } } } @@ -359,21 +279,21 @@ const char *OBJ_nid2ln(int n) if ((n >= 0) && (n < NUM_NID)) { if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) { OBJerr(OBJ_F_OBJ_NID2LN, OBJ_R_UNKNOWN_NID); - return (NULL); + return NULL; } - return (nid_objs[n].ln); + return nid_objs[n].ln; } else if (added == NULL) - return (NULL); + return NULL; else { ad.type = ADDED_NID; ad.obj = &ob; ob.nid = n; adp = lh_ADDED_OBJ_retrieve(added, &ad); if (adp != NULL) - return (adp->obj->ln); + return adp->obj->ln; else { OBJerr(OBJ_F_OBJ_NID2LN, OBJ_R_UNKNOWN_NID); - return (NULL); + return NULL; } } } @@ -386,8 +306,10 @@ static int obj_cmp(const ASN1_OBJECT *const *ap, const unsigned int *bp) j = (a->length - b->length); if (j) - return (j); - return (memcmp(a->data, b->data, a->length)); + return j; + if (a->length == 0) + return 0; + return memcmp(a->data, b->data, a->length); } IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj); @@ -398,21 +320,24 @@ int OBJ_obj2nid(const ASN1_OBJECT *a) ADDED_OBJ ad, *adp; if (a == NULL) - return (NID_undef); + return NID_undef; if (a->nid != 0) - return (a->nid); + return a->nid; + + if (a->length == 0) + return NID_undef; if (added != NULL) { ad.type = ADDED_DATA; ad.obj = (ASN1_OBJECT *)a; /* XXX: ugly but harmless */ adp = lh_ADDED_OBJ_retrieve(added, &ad); if (adp != NULL) - return (adp->obj->nid); + return adp->obj->nid; } op = OBJ_bsearch_obj(&a, obj_objs, NUM_OBJ); if (op == NULL) - return (NID_undef); - return (nid_objs[*op].nid); + return NID_undef; + return nid_objs[*op].nid; } /* @@ -425,7 +350,7 @@ int OBJ_obj2nid(const ASN1_OBJECT *a) ASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name) { int nid = NID_undef; - ASN1_OBJECT *op = NULL; + ASN1_OBJECT *op; unsigned char *buf; unsigned char *p; const unsigned char *cp; @@ -448,9 +373,13 @@ ASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name) } /* Work out total size */ j = ASN1_object_size(0, i, V_ASN1_OBJECT); + if (j < 0) + return NULL; - if ((buf = (unsigned char *)OPENSSL_malloc(j)) == NULL) + if ((buf = OPENSSL_malloc(j)) == NULL) { + OBJerr(OBJ_F_OBJ_TXT2OBJ, ERR_R_MALLOC_FAILURE); return NULL; + } p = buf; /* Write out tag+length */ @@ -477,7 +406,7 @@ int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name) buf[0] = '\0'; if ((a == NULL) || (a->data == NULL)) - return (0); + return 0; if (!no_name && (nid = OBJ_obj2nid(a)) != NID_undef) { const char *s; @@ -486,7 +415,7 @@ int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name) s = OBJ_nid2sn(nid); if (s) { if (buf) - BUF_strlcpy(buf, s, buf_len); + OPENSSL_strlcpy(buf, s, buf_len); n = strlen(s); return n; } @@ -514,7 +443,7 @@ int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name) if (!(c & 0x80)) break; if (!use_bn && (l > (ULONG_MAX >> 7L))) { - if (!bl && !(bl = BN_new())) + if (bl == NULL && (bl = BN_new()) == NULL) goto err; if (!BN_set_word(bl, l)) goto err; @@ -560,7 +489,7 @@ int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name) *buf = '\0'; buf_len--; } - BUF_strlcpy(buf, bndec, buf_len); + OPENSSL_strlcpy(buf, bndec, buf_len); if (i > buf_len) { buf += buf_len; buf_len = 0; @@ -573,10 +502,10 @@ int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name) n += i; OPENSSL_free(bndec); } else { - BIO_snprintf(tbuf, sizeof tbuf, ".%lu", l); + BIO_snprintf(tbuf, sizeof(tbuf), ".%lu", l); i = strlen(tbuf); if (buf && (buf_len > 0)) { - BUF_strlcpy(buf, tbuf, buf_len); + OPENSSL_strlcpy(buf, tbuf, buf_len); if (i > buf_len) { buf += buf_len; buf_len = 0; @@ -590,13 +519,11 @@ int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name) } } - if (bl) - BN_free(bl); + BN_free(bl); return n; err: - if (bl) - BN_free(bl); + BN_free(bl); return -1; } @@ -623,12 +550,12 @@ int OBJ_ln2nid(const char *s) ad.obj = &o; adp = lh_ADDED_OBJ_retrieve(added, &ad); if (adp != NULL) - return (adp->obj->nid); + return adp->obj->nid; } op = OBJ_bsearch_ln(&oo, ln_objs, NUM_LN); if (op == NULL) - return (NID_undef); - return (nid_objs[*op].nid); + return NID_undef; + return nid_objs[*op].nid; } int OBJ_sn2nid(const char *s) @@ -644,12 +571,12 @@ int OBJ_sn2nid(const char *s) ad.obj = &o; adp = lh_ADDED_OBJ_retrieve(added, &ad); if (adp != NULL) - return (adp->obj->nid); + return adp->obj->nid; } op = OBJ_bsearch_sn(&oo, sn_objs, NUM_SN); if (op == NULL) - return (NID_undef); - return (nid_objs[*op].nid); + return NID_undef; + return nid_objs[*op].nid; } const void *OBJ_bsearch_(const void *key, const void *base, int num, int size, @@ -668,7 +595,7 @@ const void *OBJ_bsearch_ex_(const void *key, const void *base_, int num, const char *p = NULL; if (num == 0) - return (NULL); + return NULL; l = 0; h = num; while (l < h) { @@ -704,9 +631,13 @@ const void *OBJ_bsearch_ex_(const void *key, const void *base_, int num, i--; p = &(base[i * size]); } - return (p); + return p; } +/* + * Parse a BIO sink to create some extra oid's objects. + * Line format: + */ int OBJ_create_objects(BIO *in) { char buf[512]; @@ -717,67 +648,92 @@ int OBJ_create_objects(BIO *in) s = o = NULL; i = BIO_gets(in, buf, 512); if (i <= 0) - return (num); + return num; buf[i - 1] = '\0'; - if (!isalnum((unsigned char)buf[0])) - return (num); + if (!ossl_isalnum(buf[0])) + return num; o = s = buf; - while (isdigit((unsigned char)*s) || (*s == '.')) + while (ossl_isdigit(*s) || *s == '.') s++; if (*s != '\0') { *(s++) = '\0'; - while (isspace((unsigned char)*s)) + while (ossl_isspace(*s)) s++; - if (*s == '\0') + if (*s == '\0') { s = NULL; - else { + } else { l = s; - while ((*l != '\0') && !isspace((unsigned char)*l)) + while (*l != '\0' && !ossl_isspace(*l)) l++; if (*l != '\0') { *(l++) = '\0'; - while (isspace((unsigned char)*l)) + while (ossl_isspace(*l)) l++; - if (*l == '\0') + if (*l == '\0') { l = NULL; - } else + } + } else { l = NULL; + } } - } else + } else { s = NULL; - if ((o == NULL) || (*o == '\0')) - return (num); + } + if (*o == '\0') + return num; if (!OBJ_create(o, s, l)) - return (num); + return num; num++; } - /* return(num); */ } int OBJ_create(const char *oid, const char *sn, const char *ln) { + ASN1_OBJECT *tmpoid = NULL; int ok = 0; - ASN1_OBJECT *op = NULL; - unsigned char *buf; - int i; - i = a2d_ASN1_OBJECT(NULL, 0, oid, -1); - if (i <= 0) - return (0); - - if ((buf = (unsigned char *)OPENSSL_malloc(i)) == NULL) { - OBJerr(OBJ_F_OBJ_CREATE, ERR_R_MALLOC_FAILURE); - return (0); + /* Check to see if short or long name already present */ + if ((sn != NULL && OBJ_sn2nid(sn) != NID_undef) + || (ln != NULL && OBJ_ln2nid(ln) != NID_undef)) { + OBJerr(OBJ_F_OBJ_CREATE, OBJ_R_OID_EXISTS); + return 0; } - i = a2d_ASN1_OBJECT(buf, i, oid, -1); - if (i == 0) - goto err; - op = (ASN1_OBJECT *)ASN1_OBJECT_create(OBJ_new_nid(1), buf, i, sn, ln); - if (op == NULL) + + /* Convert numerical OID string to an ASN1_OBJECT structure */ + tmpoid = OBJ_txt2obj(oid, 1); + if (tmpoid == NULL) + return 0; + + /* If NID is not NID_undef then object already exists */ + if (OBJ_obj2nid(tmpoid) != NID_undef) { + OBJerr(OBJ_F_OBJ_CREATE, OBJ_R_OID_EXISTS); goto err; - ok = OBJ_add_object(op); + } + + tmpoid->nid = OBJ_new_nid(1); + tmpoid->sn = (char *)sn; + tmpoid->ln = (char *)ln; + + ok = OBJ_add_object(tmpoid); + + tmpoid->sn = NULL; + tmpoid->ln = NULL; + err: - ASN1_OBJECT_free(op); - OPENSSL_free(buf); - return (ok); + ASN1_OBJECT_free(tmpoid); + return ok; +} + +size_t OBJ_length(const ASN1_OBJECT *obj) +{ + if (obj == NULL) + return 0; + return obj->length; +} + +const unsigned char *OBJ_get0_data(const ASN1_OBJECT *obj) +{ + if (obj == NULL) + return NULL; + return obj->data; }