Home | History | Annotate | Download | only in x509v3
      1 /* v3_genn.c */
      2 /*
      3  * Written by Dr Stephen N Henson (steve (at) openssl.org) for the OpenSSL project
      4  * 1999.
      5  */
      6 /* ====================================================================
      7  * Copyright (c) 1999-2008 The OpenSSL Project.  All rights reserved.
      8  *
      9  * Redistribution and use in source and binary forms, with or without
     10  * modification, are permitted provided that the following conditions
     11  * are met:
     12  *
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  *
     16  * 2. Redistributions in binary form must reproduce the above copyright
     17  *    notice, this list of conditions and the following disclaimer in
     18  *    the documentation and/or other materials provided with the
     19  *    distribution.
     20  *
     21  * 3. All advertising materials mentioning features or use of this
     22  *    software must display the following acknowledgment:
     23  *    "This product includes software developed by the OpenSSL Project
     24  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
     25  *
     26  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
     27  *    endorse or promote products derived from this software without
     28  *    prior written permission. For written permission, please contact
     29  *    licensing (at) OpenSSL.org.
     30  *
     31  * 5. Products derived from this software may not be called "OpenSSL"
     32  *    nor may "OpenSSL" appear in their names without prior written
     33  *    permission of the OpenSSL Project.
     34  *
     35  * 6. Redistributions of any form whatsoever must retain the following
     36  *    acknowledgment:
     37  *    "This product includes software developed by the OpenSSL Project
     38  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
     39  *
     40  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
     41  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     43  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
     44  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     45  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     46  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     47  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     49  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     50  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
     51  * OF THE POSSIBILITY OF SUCH DAMAGE.
     52  * ====================================================================
     53  *
     54  * This product includes cryptographic software written by Eric Young
     55  * (eay (at) cryptsoft.com).  This product includes software written by Tim
     56  * Hudson (tjh (at) cryptsoft.com). */
     57 
     58 #include <stdio.h>
     59 
     60 #include <openssl/asn1t.h>
     61 #include <openssl/conf.h>
     62 #include <openssl/obj.h>
     63 #include <openssl/x509v3.h>
     64 
     65 
     66 ASN1_SEQUENCE(OTHERNAME) = {
     67         ASN1_SIMPLE(OTHERNAME, type_id, ASN1_OBJECT),
     68         /* Maybe have a true ANY DEFINED BY later */
     69         ASN1_EXP(OTHERNAME, value, ASN1_ANY, 0)
     70 } ASN1_SEQUENCE_END(OTHERNAME)
     71 
     72 IMPLEMENT_ASN1_FUNCTIONS(OTHERNAME)
     73 
     74 ASN1_SEQUENCE(EDIPARTYNAME) = {
     75         ASN1_IMP_OPT(EDIPARTYNAME, nameAssigner, DIRECTORYSTRING, 0),
     76         ASN1_IMP_OPT(EDIPARTYNAME, partyName, DIRECTORYSTRING, 1)
     77 } ASN1_SEQUENCE_END(EDIPARTYNAME)
     78 
     79 IMPLEMENT_ASN1_FUNCTIONS(EDIPARTYNAME)
     80 
     81 ASN1_CHOICE(GENERAL_NAME) = {
     82         ASN1_IMP(GENERAL_NAME, d.otherName, OTHERNAME, GEN_OTHERNAME),
     83         ASN1_IMP(GENERAL_NAME, d.rfc822Name, ASN1_IA5STRING, GEN_EMAIL),
     84         ASN1_IMP(GENERAL_NAME, d.dNSName, ASN1_IA5STRING, GEN_DNS),
     85         /* Don't decode this */
     86         ASN1_IMP(GENERAL_NAME, d.x400Address, ASN1_SEQUENCE, GEN_X400),
     87         /* X509_NAME is a CHOICE type so use EXPLICIT */
     88         ASN1_EXP(GENERAL_NAME, d.directoryName, X509_NAME, GEN_DIRNAME),
     89         ASN1_IMP(GENERAL_NAME, d.ediPartyName, EDIPARTYNAME, GEN_EDIPARTY),
     90         ASN1_IMP(GENERAL_NAME, d.uniformResourceIdentifier, ASN1_IA5STRING, GEN_URI),
     91         ASN1_IMP(GENERAL_NAME, d.iPAddress, ASN1_OCTET_STRING, GEN_IPADD),
     92         ASN1_IMP(GENERAL_NAME, d.registeredID, ASN1_OBJECT, GEN_RID)
     93 } ASN1_CHOICE_END(GENERAL_NAME)
     94 
     95 IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAME)
     96 
     97 ASN1_ITEM_TEMPLATE(GENERAL_NAMES) =
     98         ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, GeneralNames, GENERAL_NAME)
     99 ASN1_ITEM_TEMPLATE_END(GENERAL_NAMES)
    100 
    101 IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAMES)
    102 
    103 GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a)
    104 {
    105     return (GENERAL_NAME *)ASN1_dup((i2d_of_void *)i2d_GENERAL_NAME,
    106                                     (d2i_of_void *)d2i_GENERAL_NAME,
    107                                     (char *)a);
    108 }
    109 
    110 /* Returns 0 if they are equal, != 0 otherwise. */
    111 int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b)
    112 {
    113     int result = -1;
    114 
    115     if (!a || !b || a->type != b->type)
    116         return -1;
    117     switch (a->type) {
    118     case GEN_X400:
    119     case GEN_EDIPARTY:
    120         result = ASN1_TYPE_cmp(a->d.other, b->d.other);
    121         break;
    122 
    123     case GEN_OTHERNAME:
    124         result = OTHERNAME_cmp(a->d.otherName, b->d.otherName);
    125         break;
    126 
    127     case GEN_EMAIL:
    128     case GEN_DNS:
    129     case GEN_URI:
    130         result = ASN1_STRING_cmp(a->d.ia5, b->d.ia5);
    131         break;
    132 
    133     case GEN_DIRNAME:
    134         result = X509_NAME_cmp(a->d.dirn, b->d.dirn);
    135         break;
    136 
    137     case GEN_IPADD:
    138         result = ASN1_OCTET_STRING_cmp(a->d.ip, b->d.ip);
    139         break;
    140 
    141     case GEN_RID:
    142         result = OBJ_cmp(a->d.rid, b->d.rid);
    143         break;
    144     }
    145     return result;
    146 }
    147 
    148 /* Returns 0 if they are equal, != 0 otherwise. */
    149 int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b)
    150 {
    151     int result = -1;
    152 
    153     if (!a || !b)
    154         return -1;
    155     /* Check their type first. */
    156     if ((result = OBJ_cmp(a->type_id, b->type_id)) != 0)
    157         return result;
    158     /* Check the value. */
    159     result = ASN1_TYPE_cmp(a->value, b->value);
    160     return result;
    161 }
    162 
    163 void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value)
    164 {
    165     switch (type) {
    166     case GEN_X400:
    167     case GEN_EDIPARTY:
    168         a->d.other = value;
    169         break;
    170 
    171     case GEN_OTHERNAME:
    172         a->d.otherName = value;
    173         break;
    174 
    175     case GEN_EMAIL:
    176     case GEN_DNS:
    177     case GEN_URI:
    178         a->d.ia5 = value;
    179         break;
    180 
    181     case GEN_DIRNAME:
    182         a->d.dirn = value;
    183         break;
    184 
    185     case GEN_IPADD:
    186         a->d.ip = value;
    187         break;
    188 
    189     case GEN_RID:
    190         a->d.rid = value;
    191         break;
    192     }
    193     a->type = type;
    194 }
    195 
    196 void *GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype)
    197 {
    198     if (ptype)
    199         *ptype = a->type;
    200     switch (a->type) {
    201     case GEN_X400:
    202     case GEN_EDIPARTY:
    203         return a->d.other;
    204 
    205     case GEN_OTHERNAME:
    206         return a->d.otherName;
    207 
    208     case GEN_EMAIL:
    209     case GEN_DNS:
    210     case GEN_URI:
    211         return a->d.ia5;
    212 
    213     case GEN_DIRNAME:
    214         return a->d.dirn;
    215 
    216     case GEN_IPADD:
    217         return a->d.ip;
    218 
    219     case GEN_RID:
    220         return a->d.rid;
    221 
    222     default:
    223         return NULL;
    224     }
    225 }
    226 
    227 int GENERAL_NAME_set0_othername(GENERAL_NAME *gen,
    228                                 ASN1_OBJECT *oid, ASN1_TYPE *value)
    229 {
    230     OTHERNAME *oth;
    231     oth = OTHERNAME_new();
    232     if (!oth)
    233         return 0;
    234     oth->type_id = oid;
    235     oth->value = value;
    236     GENERAL_NAME_set0_value(gen, GEN_OTHERNAME, oth);
    237     return 1;
    238 }
    239 
    240 int GENERAL_NAME_get0_otherName(GENERAL_NAME *gen,
    241                                 ASN1_OBJECT **poid, ASN1_TYPE **pvalue)
    242 {
    243     if (gen->type != GEN_OTHERNAME)
    244         return 0;
    245     if (poid)
    246         *poid = gen->d.otherName->type_id;
    247     if (pvalue)
    248         *pvalue = gen->d.otherName->value;
    249     return 1;
    250 }
    251