155714Skris/* crypto/asn1/x_x509.c */
255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
355714Skris * All rights reserved.
455714Skris *
555714Skris * This package is an SSL implementation written
655714Skris * by Eric Young (eay@cryptsoft.com).
755714Skris * The implementation was written so as to conform with Netscapes SSL.
8280297Sjkim *
955714Skris * This library is free for commercial and non-commercial use as long as
1055714Skris * the following conditions are aheared to.  The following conditions
1155714Skris * apply to all code found in this distribution, be it the RC4, RSA,
1255714Skris * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1355714Skris * included with this distribution is covered by the same copyright terms
1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15280297Sjkim *
1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in
1755714Skris * the code are not to be removed.
1855714Skris * If this package is used in a product, Eric Young should be given attribution
1955714Skris * as the author of the parts of the library used.
2055714Skris * This can be in the form of a textual message at program startup or
2155714Skris * in documentation (online or textual) provided with the package.
22280297Sjkim *
2355714Skris * Redistribution and use in source and binary forms, with or without
2455714Skris * modification, are permitted provided that the following conditions
2555714Skris * are met:
2655714Skris * 1. Redistributions of source code must retain the copyright
2755714Skris *    notice, this list of conditions and the following disclaimer.
2855714Skris * 2. Redistributions in binary form must reproduce the above copyright
2955714Skris *    notice, this list of conditions and the following disclaimer in the
3055714Skris *    documentation and/or other materials provided with the distribution.
3155714Skris * 3. All advertising materials mentioning features or use of this software
3255714Skris *    must display the following acknowledgement:
3355714Skris *    "This product includes cryptographic software written by
3455714Skris *     Eric Young (eay@cryptsoft.com)"
3555714Skris *    The word 'cryptographic' can be left out if the rouines from the library
3655714Skris *    being used are not cryptographic related :-).
37280297Sjkim * 4. If you include any Windows specific code (or a derivative thereof) from
3855714Skris *    the apps directory (application code) you must include an acknowledgement:
3955714Skris *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40280297Sjkim *
4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4455714Skris * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5155714Skris * SUCH DAMAGE.
52280297Sjkim *
5355714Skris * The licence and distribution terms for any publically available version or
5455714Skris * derivative of this code cannot be changed.  i.e. this code cannot simply be
5555714Skris * copied and put under another distribution licence
5655714Skris * [including the GNU Public Licence.]
5755714Skris */
5855714Skris
5955714Skris#include <stdio.h>
6055714Skris#include "cryptlib.h"
6155714Skris#include <openssl/evp.h>
62109998Smarkm#include <openssl/asn1t.h>
6355714Skris#include <openssl/x509.h>
6468651Skris#include <openssl/x509v3.h>
6555714Skris
66215697SsimonASN1_SEQUENCE_enc(X509_CINF, enc, 0) = {
67280297Sjkim        ASN1_EXP_OPT(X509_CINF, version, ASN1_INTEGER, 0),
68280297Sjkim        ASN1_SIMPLE(X509_CINF, serialNumber, ASN1_INTEGER),
69280297Sjkim        ASN1_SIMPLE(X509_CINF, signature, X509_ALGOR),
70280297Sjkim        ASN1_SIMPLE(X509_CINF, issuer, X509_NAME),
71280297Sjkim        ASN1_SIMPLE(X509_CINF, validity, X509_VAL),
72280297Sjkim        ASN1_SIMPLE(X509_CINF, subject, X509_NAME),
73280297Sjkim        ASN1_SIMPLE(X509_CINF, key, X509_PUBKEY),
74280297Sjkim        ASN1_IMP_OPT(X509_CINF, issuerUID, ASN1_BIT_STRING, 1),
75280297Sjkim        ASN1_IMP_OPT(X509_CINF, subjectUID, ASN1_BIT_STRING, 2),
76280297Sjkim        ASN1_EXP_SEQUENCE_OF_OPT(X509_CINF, extensions, X509_EXTENSION, 3)
77215697Ssimon} ASN1_SEQUENCE_END_enc(X509_CINF, X509_CINF)
7859191Skris
79109998SmarkmIMPLEMENT_ASN1_FUNCTIONS(X509_CINF)
80109998Smarkm/* X509 top level structure needs a bit of customisation */
8155714Skris
82160814Ssimonextern void policy_cache_free(X509_POLICY_CACHE *cache);
83160814Ssimon
84238405Sjkimstatic int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
85280297Sjkim                   void *exarg)
86109998Smarkm{
87280297Sjkim    X509 *ret = (X509 *)*pval;
8855714Skris
89280297Sjkim    switch (operation) {
9055714Skris
91280297Sjkim    case ASN1_OP_NEW_POST:
92280297Sjkim        ret->valid = 0;
93280297Sjkim        ret->name = NULL;
94280297Sjkim        ret->ex_flags = 0;
95280297Sjkim        ret->ex_pathlen = -1;
96280297Sjkim        ret->skid = NULL;
97280297Sjkim        ret->akid = NULL;
98167612Ssimon#ifndef OPENSSL_NO_RFC3779
99280297Sjkim        ret->rfc3779_addr = NULL;
100280297Sjkim        ret->rfc3779_asid = NULL;
101167612Ssimon#endif
102280297Sjkim        ret->aux = NULL;
103280297Sjkim        ret->crldp = NULL;
104280297Sjkim        CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data);
105280297Sjkim        break;
10655714Skris
107280297Sjkim    case ASN1_OP_D2I_POST:
108280297Sjkim        if (ret->name != NULL)
109280297Sjkim            OPENSSL_free(ret->name);
110280297Sjkim        ret->name = X509_NAME_oneline(ret->cert_info->subject, NULL, 0);
111280297Sjkim        break;
11255714Skris
113280297Sjkim    case ASN1_OP_FREE_POST:
114280297Sjkim        CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data);
115280297Sjkim        X509_CERT_AUX_free(ret->aux);
116280297Sjkim        ASN1_OCTET_STRING_free(ret->skid);
117280297Sjkim        AUTHORITY_KEYID_free(ret->akid);
118280297Sjkim        CRL_DIST_POINTS_free(ret->crldp);
119280297Sjkim        policy_cache_free(ret->policy_cache);
120280297Sjkim        GENERAL_NAMES_free(ret->altname);
121280297Sjkim        NAME_CONSTRAINTS_free(ret->nc);
122167612Ssimon#ifndef OPENSSL_NO_RFC3779
123280297Sjkim        sk_IPAddressFamily_pop_free(ret->rfc3779_addr, IPAddressFamily_free);
124280297Sjkim        ASIdentifiers_free(ret->rfc3779_asid);
125167612Ssimon#endif
12655714Skris
127280297Sjkim        if (ret->name != NULL)
128280297Sjkim            OPENSSL_free(ret->name);
129280297Sjkim        break;
130109998Smarkm
131280297Sjkim    }
13255714Skris
133280297Sjkim    return 1;
13455714Skris
135109998Smarkm}
13655714Skris
137109998SmarkmASN1_SEQUENCE_ref(X509, x509_cb, CRYPTO_LOCK_X509) = {
138280297Sjkim        ASN1_SIMPLE(X509, cert_info, X509_CINF),
139280297Sjkim        ASN1_SIMPLE(X509, sig_alg, X509_ALGOR),
140280297Sjkim        ASN1_SIMPLE(X509, signature, ASN1_BIT_STRING)
141109998Smarkm} ASN1_SEQUENCE_END_ref(X509, X509)
14255714Skris
143109998SmarkmIMPLEMENT_ASN1_FUNCTIONS(X509)
144280297Sjkim
145109998SmarkmIMPLEMENT_ASN1_DUP_FUNCTION(X509)
14655714Skris
14759191Skrisint X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
148280297Sjkim                          CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
149280297Sjkim{
150280297Sjkim    return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509, argl, argp,
151280297Sjkim                                   new_func, dup_func, free_func);
152280297Sjkim}
15359191Skris
15459191Skrisint X509_set_ex_data(X509 *r, int idx, void *arg)
155280297Sjkim{
156280297Sjkim    return (CRYPTO_set_ex_data(&r->ex_data, idx, arg));
157280297Sjkim}
15859191Skris
15959191Skrisvoid *X509_get_ex_data(X509 *r, int idx)
160280297Sjkim{
161280297Sjkim    return (CRYPTO_get_ex_data(&r->ex_data, idx));
162280297Sjkim}
16359191Skris
164280297Sjkim/*
165280297Sjkim * X509_AUX ASN1 routines. X509_AUX is the name given to a certificate with
166280297Sjkim * extra info tagged on the end. Since these functions set how a certificate
167280297Sjkim * is trusted they should only be used when the certificate comes from a
168280297Sjkim * reliable source such as local storage.
16959191Skris */
17059191Skris
171160814SsimonX509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length)
17259191Skris{
173280297Sjkim    const unsigned char *q;
174280297Sjkim    X509 *ret;
175280297Sjkim    int freeret = 0;
176280297Sjkim
177280297Sjkim    /* Save start position */
178280297Sjkim    q = *pp;
179280297Sjkim
180284283Sjkim    if (!a || *a == NULL) {
181280297Sjkim        freeret = 1;
182280297Sjkim    }
183291719Sjkim    ret = d2i_X509(a, &q, length);
184280297Sjkim    /* If certificate unreadable then forget it */
185280297Sjkim    if (!ret)
186280297Sjkim        return NULL;
187280297Sjkim    /* update length */
188291719Sjkim    length -= q - *pp;
189291719Sjkim    if (length > 0 && !d2i_X509_CERT_AUX(&ret->aux, &q, length))
190280297Sjkim        goto err;
191291719Sjkim    *pp = q;
192280297Sjkim    return ret;
193280297Sjkim err:
194284283Sjkim    if (freeret) {
195280297Sjkim        X509_free(ret);
196280297Sjkim        if (a)
197280297Sjkim            *a = NULL;
198280297Sjkim    }
199280297Sjkim    return NULL;
20059191Skris}
20159191Skris
202306198Sjkim/*
203306198Sjkim * Serialize trusted certificate to *pp or just return the required buffer
204306198Sjkim * length if pp == NULL.  We ultimately want to avoid modifying *pp in the
205306198Sjkim * error path, but that depends on similar hygiene in lower-level functions.
206306198Sjkim * Here we avoid compounding the problem.
207306198Sjkim */
208306198Sjkimstatic int i2d_x509_aux_internal(X509 *a, unsigned char **pp)
20959191Skris{
210298998Sjkim    int length, tmplen;
211298998Sjkim    unsigned char *start = pp != NULL ? *pp : NULL;
212306198Sjkim
213306198Sjkim    OPENSSL_assert(pp == NULL || *pp != NULL);
214306198Sjkim
215306198Sjkim    /*
216306198Sjkim     * This might perturb *pp on error, but fixing that belongs in i2d_X509()
217306198Sjkim     * not here.  It should be that if a == NULL length is zero, but we check
218306198Sjkim     * both just in case.
219306198Sjkim     */
220280297Sjkim    length = i2d_X509(a, pp);
221306198Sjkim    if (length <= 0 || a == NULL)
222298998Sjkim        return length;
223298998Sjkim
224298998Sjkim    tmplen = i2d_X509_CERT_AUX(a->aux, pp);
225298998Sjkim    if (tmplen < 0) {
226298998Sjkim        if (start != NULL)
227298998Sjkim            *pp = start;
228298998Sjkim        return tmplen;
229298998Sjkim    }
230298998Sjkim    length += tmplen;
231298998Sjkim
232280297Sjkim    return length;
23359191Skris}
234290207Sjkim
235306198Sjkim/*
236306198Sjkim * Serialize trusted certificate to *pp, or just return the required buffer
237306198Sjkim * length if pp == NULL.
238306198Sjkim *
239306198Sjkim * When pp is not NULL, but *pp == NULL, we allocate the buffer, but since
240306198Sjkim * we're writing two ASN.1 objects back to back, we can't have i2d_X509() do
241306198Sjkim * the allocation, nor can we allow i2d_X509_CERT_AUX() to increment the
242306198Sjkim * allocated buffer.
243306198Sjkim */
244306198Sjkimint i2d_X509_AUX(X509 *a, unsigned char **pp)
245306198Sjkim{
246306198Sjkim    int length;
247306198Sjkim    unsigned char *tmp;
248306198Sjkim
249306198Sjkim    /* Buffer provided by caller */
250306198Sjkim    if (pp == NULL || *pp != NULL)
251306198Sjkim        return i2d_x509_aux_internal(a, pp);
252306198Sjkim
253306198Sjkim    /* Obtain the combined length */
254306198Sjkim    if ((length = i2d_x509_aux_internal(a, NULL)) <= 0)
255306198Sjkim        return length;
256306198Sjkim
257306198Sjkim    /* Allocate requisite combined storage */
258306198Sjkim    *pp = tmp = OPENSSL_malloc(length);
259306198Sjkim    if (tmp == NULL)
260306198Sjkim        return -1; /* Push error onto error stack? */
261306198Sjkim
262306198Sjkim    /* Encode, but keep *pp at the originally malloced pointer */
263306198Sjkim    length = i2d_x509_aux_internal(a, &tmp);
264306198Sjkim    if (length <= 0) {
265306198Sjkim        OPENSSL_free(*pp);
266306198Sjkim        *pp = NULL;
267306198Sjkim    }
268306198Sjkim    return length;
269306198Sjkim}
270306198Sjkim
271290207Sjkimint i2d_re_X509_tbs(X509 *x, unsigned char **pp)
272290207Sjkim{
273290207Sjkim    x->cert_info->enc.modified = 1;
274290207Sjkim    return i2d_X509_CINF(x->cert_info, pp);
275290207Sjkim}
276290207Sjkim
277290207Sjkimvoid X509_get0_signature(ASN1_BIT_STRING **psig, X509_ALGOR **palg,
278290207Sjkim                         const X509 *x)
279290207Sjkim{
280290207Sjkim    if (psig)
281290207Sjkim        *psig = x->signature;
282290207Sjkim    if (palg)
283290207Sjkim        *palg = x->sig_alg;
284290207Sjkim}
285290207Sjkim
286290207Sjkimint X509_get_signature_nid(const X509 *x)
287290207Sjkim{
288290207Sjkim    return OBJ_obj2nid(x->sig_alg->algorithm);
289290207Sjkim}
290