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 IMPLEMENT_ASN1_DUP_FUNCTION(GENERAL_NAME)
    104 
    105 /* Returns 0 if they are equal, != 0 otherwise. */
    106 int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b)
    107 {
    108     int result = -1;
    109 
    110     if (!a || !b || a->type != b->type)
    111         return -1;
    112     switch (a->type) {
    113     case GEN_X400:
    114     case GEN_EDIPARTY:
    115         result = ASN1_TYPE_cmp(a->d.other, b->d.other);
    116         break;
    117 
    118     case GEN_OTHERNAME:
    119         result = OTHERNAME_cmp(a->d.otherName, b->d.otherName);
    120         break;
    121 
    122     case GEN_EMAIL:
    123     case GEN_DNS:
    124     case GEN_URI:
    125         result = ASN1_STRING_cmp(a->d.ia5, b->d.ia5);
    126         break;
    127 
    128     case GEN_DIRNAME:
    129         result = X509_NAME_cmp(a->d.dirn, b->d.dirn);
    130         break;
    131 
    132     case GEN_IPADD:
    133         result = ASN1_OCTET_STRING_cmp(a->d.ip, b->d.ip);
    134         break;
    135 
    136     case GEN_RID:
    137         result = OBJ_cmp(a->d.rid, b->d.rid);
    138         break;
    139     }
    140     return result;
    141 }
    142 
    143 /* Returns 0 if they are equal, != 0 otherwise. */
    144 int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b)
    145 {
    146     int result = -1;
    147 
    148     if (!a || !b)
    149         return -1;
    150     /* Check their type first. */
    151     if ((result = OBJ_cmp(a->type_id, b->type_id)) != 0)
    152         return result;
    153     /* Check the value. */
    154     result = ASN1_TYPE_cmp(a->value, b->value);
    155     return result;
    156 }
    157 
    158 void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value)
    159 {
    160     switch (type) {
    161     case GEN_X400:
    162     case GEN_EDIPARTY:
    163         a->d.other = value;
    164         break;
    165 
    166     case GEN_OTHERNAME:
    167         a->d.otherName = value;
    168         break;
    169 
    170     case GEN_EMAIL:
    171     case GEN_DNS:
    172     case GEN_URI:
    173         a->d.ia5 = value;
    174         break;
    175 
    176     case GEN_DIRNAME:
    177         a->d.dirn = value;
    178         break;
    179 
    180     case GEN_IPADD:
    181         a->d.ip = value;
    182         break;
    183 
    184     case GEN_RID:
    185         a->d.rid = value;
    186         break;
    187     }
    188     a->type = type;
    189 }
    190 
    191 void *GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype)
    192 {
    193     if (ptype)
    194         *ptype = a->type;
    195     switch (a->type) {
    196     case GEN_X400:
    197     case GEN_EDIPARTY:
    198         return a->d.other;
    199 
    200     case GEN_OTHERNAME:
    201         return a->d.otherName;
    202 
    203     case GEN_EMAIL:
    204     case GEN_DNS:
    205     case GEN_URI:
    206         return a->d.ia5;
    207 
    208     case GEN_DIRNAME:
    209         return a->d.dirn;
    210 
    211     case GEN_IPADD:
    212         return a->d.ip;
    213 
    214     case GEN_RID:
    215         return a->d.rid;
    216 
    217     default:
    218         return NULL;
    219     }
    220 }
    221 
    222 int GENERAL_NAME_set0_othername(GENERAL_NAME *gen,
    223                                 ASN1_OBJECT *oid, ASN1_TYPE *value)
    224 {
    225     OTHERNAME *oth;
    226     oth = OTHERNAME_new();
    227     if (!oth)
    228         return 0;
    229     ASN1_TYPE_free(oth->value);
    230     oth->type_id = oid;
    231     oth->value = value;
    232     GENERAL_NAME_set0_value(gen, GEN_OTHERNAME, oth);
    233     return 1;
    234 }
    235 
    236 int GENERAL_NAME_get0_otherName(GENERAL_NAME *gen,
    237                                 ASN1_OBJECT **poid, ASN1_TYPE **pvalue)
    238 {
    239     if (gen->type != GEN_OTHERNAME)
    240         return 0;
    241     if (poid)
    242         *poid = gen->d.otherName->type_id;
    243     if (pvalue)
    244         *pvalue = gen->d.otherName->value;
    245     return 1;
    246 }
    247