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