1d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * All rights reserved. 3d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 4d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * This package is an SSL implementation written 5d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * by Eric Young (eay@cryptsoft.com). 6d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * The implementation was written so as to conform with Netscapes SSL. 7d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 8d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * This library is free for commercial and non-commercial use as long as 9d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * the following conditions are aheared to. The following conditions 10d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * apply to all code found in this distribution, be it the RC4, RSA, 11d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * lhash, DES, etc., code; not just the SSL code. The SSL documentation 12d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * included with this distribution is covered by the same copyright terms 13d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * except that the holder is Tim Hudson (tjh@cryptsoft.com). 14d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 15d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Copyright remains Eric Young's, and as such any Copyright notices in 16d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * the code are not to be removed. 17d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * If this package is used in a product, Eric Young should be given attribution 18d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * as the author of the parts of the library used. 19d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * This can be in the form of a textual message at program startup or 20d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * in documentation (online or textual) provided with the package. 21d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 22d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Redistribution and use in source and binary forms, with or without 23d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * modification, are permitted provided that the following conditions 24d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * are met: 25d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 1. Redistributions of source code must retain the copyright 26d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * notice, this list of conditions and the following disclaimer. 27d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 2. Redistributions in binary form must reproduce the above copyright 28d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * notice, this list of conditions and the following disclaimer in the 29d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * documentation and/or other materials provided with the distribution. 30d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 3. All advertising materials mentioning features or use of this software 31d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * must display the following acknowledgement: 32d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * "This product includes cryptographic software written by 33d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Eric Young (eay@cryptsoft.com)" 34d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * The word 'cryptographic' can be left out if the rouines from the library 35d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * being used are not cryptographic related :-). 36d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 4. If you include any Windows specific code (or a derivative thereof) from 37d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * the apps directory (application code) you must include an acknowledgement: 38d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 39d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 40d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 41d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 43d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 44d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 45d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 46d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 48d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 49d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 50d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * SUCH DAMAGE. 51d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 52d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * The licence and distribution terms for any publically available version or 53d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * derivative of this code cannot be changed. i.e. this code cannot simply be 54d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * copied and put under another distribution licence 55d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * [including the GNU Public Licence.] */ 56d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 57d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/x509.h> 58d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 59d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <string.h> 60d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 61d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/asn1.h> 62d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/err.h> 63d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/mem.h> 64d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/obj.h> 65d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/x509v3.h> 66d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 67e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#include "../internal.h" 68e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 694969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin/* 704969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin * Although this file is in crypto/x509 for layering purposes, it emits 714969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin * errors from the ASN.1 module for OpenSSL compatibility. 724969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin */ 73e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 744969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin#define ASN1_GEN_FLAG 0x10000 754969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin#define ASN1_GEN_FLAG_IMP (ASN1_GEN_FLAG|1) 764969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin#define ASN1_GEN_FLAG_EXP (ASN1_GEN_FLAG|2) 774969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin#define ASN1_GEN_FLAG_TAG (ASN1_GEN_FLAG|3) 784969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin#define ASN1_GEN_FLAG_BITWRAP (ASN1_GEN_FLAG|4) 794969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin#define ASN1_GEN_FLAG_OCTWRAP (ASN1_GEN_FLAG|5) 804969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin#define ASN1_GEN_FLAG_SEQWRAP (ASN1_GEN_FLAG|6) 814969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin#define ASN1_GEN_FLAG_SETWRAP (ASN1_GEN_FLAG|7) 824969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin#define ASN1_GEN_FLAG_FORMAT (ASN1_GEN_FLAG|8) 83d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 844969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin#define ASN1_GEN_STR(str,val) {str, sizeof(str) - 1, val} 85d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 864969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin#define ASN1_FLAG_EXP_MAX 20 87f6200e70eccb73d7a8a6940d081918f5a2b98fadRobert Sloan/* Maximum number of nested sequences */ 88f6200e70eccb73d7a8a6940d081918f5a2b98fadRobert Sloan#define ASN1_GEN_SEQ_MAX_DEPTH 50 89d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 90d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* Input formats */ 91d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 92d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* ASCII: default */ 934969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin#define ASN1_GEN_FORMAT_ASCII 1 94d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* UTF8 */ 954969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin#define ASN1_GEN_FORMAT_UTF8 2 96d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* Hex */ 974969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin#define ASN1_GEN_FORMAT_HEX 3 98d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* List of bits */ 994969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin#define ASN1_GEN_FORMAT_BITLIST 4 1004969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 1014969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjaminstruct tag_name_st { 1024969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin const char *strnam; 1034969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin int len; 1044969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin int tag; 1054969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin}; 1064969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 1074969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamintypedef struct { 1084969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin int exp_tag; 1094969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin int exp_class; 1104969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin int exp_constructed; 1114969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin int exp_pad; 1124969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin long exp_len; 1134969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin} tag_exp_type; 1144969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 1154969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamintypedef struct { 1164969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin int imp_tag; 1174969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin int imp_class; 1184969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin int utype; 1194969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin int format; 1204969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin const char *str; 1214969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin tag_exp_type exp_list[ASN1_FLAG_EXP_MAX]; 1224969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin int exp_count; 1234969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin} tag_exp_arg; 124d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 125f6200e70eccb73d7a8a6940d081918f5a2b98fadRobert Sloanstatic ASN1_TYPE *generate_v3(char *str, X509V3_CTX *cnf, int depth, 126f6200e70eccb73d7a8a6940d081918f5a2b98fadRobert Sloan int *perr); 127d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int bitstr_cb(const char *elem, int len, void *bitstr); 128d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int asn1_cb(const char *elem, int len, void *bitstr); 1294969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjaminstatic int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, 1304969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin int exp_constructed, int exp_pad, int imp_ok); 1314969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjaminstatic int parse_tagging(const char *vstart, int vlen, int *ptag, 1324969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin int *pclass); 133f6200e70eccb73d7a8a6940d081918f5a2b98fadRobert Sloanstatic ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf, 134f6200e70eccb73d7a8a6940d081918f5a2b98fadRobert Sloan int depth, int *perr); 135d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic ASN1_TYPE *asn1_str2type(const char *str, int format, int utype); 136d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int asn1_str2tag(const char *tagstr, int len); 137d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 138d9e397b599b13d642138480a28c14db7a136bf0Adam LangleyASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf) 1394969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin{ 1404969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin X509V3_CTX cnf; 141d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 1424969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!nconf) 1434969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return ASN1_generate_v3(str, NULL); 144d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 1454969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin X509V3_set_nconf(&cnf, nconf); 1464969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return ASN1_generate_v3(str, &cnf); 1474969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin} 148d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 149d9e397b599b13d642138480a28c14db7a136bf0Adam LangleyASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf) 1504969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin{ 151f6200e70eccb73d7a8a6940d081918f5a2b98fadRobert Sloan int err = 0; 152f6200e70eccb73d7a8a6940d081918f5a2b98fadRobert Sloan ASN1_TYPE *ret = generate_v3(str, cnf, 0, &err); 153f6200e70eccb73d7a8a6940d081918f5a2b98fadRobert Sloan if (err) 154f6200e70eccb73d7a8a6940d081918f5a2b98fadRobert Sloan OPENSSL_PUT_ERROR(ASN1, err); 155f6200e70eccb73d7a8a6940d081918f5a2b98fadRobert Sloan return ret; 156f6200e70eccb73d7a8a6940d081918f5a2b98fadRobert Sloan} 157f6200e70eccb73d7a8a6940d081918f5a2b98fadRobert Sloan 158f6200e70eccb73d7a8a6940d081918f5a2b98fadRobert Sloanstatic ASN1_TYPE *generate_v3(char *str, X509V3_CTX *cnf, int depth, 159f6200e70eccb73d7a8a6940d081918f5a2b98fadRobert Sloan int *perr) 160f6200e70eccb73d7a8a6940d081918f5a2b98fadRobert Sloan{ 1614969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_TYPE *ret; 1624969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin tag_exp_arg asn1_tags; 1634969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin tag_exp_type *etmp; 1644969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 1654969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin int i, len; 1664969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 1674969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin unsigned char *orig_der = NULL, *new_der = NULL; 1684969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin const unsigned char *cpy_start; 1694969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin unsigned char *p; 1704969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin const unsigned char *cp; 1714969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin int cpy_len; 1724969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin long hdr_len = 0; 1734969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin int hdr_constructed = 0, hdr_tag, hdr_class; 1744969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin int r; 1754969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 1764969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin asn1_tags.imp_tag = -1; 1774969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin asn1_tags.imp_class = -1; 1784969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin asn1_tags.format = ASN1_GEN_FORMAT_ASCII; 1794969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin asn1_tags.exp_count = 0; 180f6200e70eccb73d7a8a6940d081918f5a2b98fadRobert Sloan if (CONF_parse_list(str, ',', 1, asn1_cb, &asn1_tags) != 0) { 181f6200e70eccb73d7a8a6940d081918f5a2b98fadRobert Sloan *perr = ASN1_R_UNKNOWN_TAG; 1824969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return NULL; 183f6200e70eccb73d7a8a6940d081918f5a2b98fadRobert Sloan } 1844969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 1854969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if ((asn1_tags.utype == V_ASN1_SEQUENCE) 1864969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin || (asn1_tags.utype == V_ASN1_SET)) { 1874969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!cnf) { 188f6200e70eccb73d7a8a6940d081918f5a2b98fadRobert Sloan *perr = ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG; 1894969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return NULL; 1904969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 191f6200e70eccb73d7a8a6940d081918f5a2b98fadRobert Sloan if (depth >= ASN1_GEN_SEQ_MAX_DEPTH) { 192f6200e70eccb73d7a8a6940d081918f5a2b98fadRobert Sloan *perr = ASN1_R_ILLEGAL_NESTED_TAGGING; 193f6200e70eccb73d7a8a6940d081918f5a2b98fadRobert Sloan return NULL; 194f6200e70eccb73d7a8a6940d081918f5a2b98fadRobert Sloan } 195f6200e70eccb73d7a8a6940d081918f5a2b98fadRobert Sloan ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf, depth, perr); 1964969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } else 1974969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ret = asn1_str2type(asn1_tags.str, asn1_tags.format, asn1_tags.utype); 1984969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 1994969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!ret) 2004969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return NULL; 2014969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 2024969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* If no tagging return base type */ 2034969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if ((asn1_tags.imp_tag == -1) && (asn1_tags.exp_count == 0)) 2044969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return ret; 2054969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 2064969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* Generate the encoding */ 2074969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin cpy_len = i2d_ASN1_TYPE(ret, &orig_der); 2084969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_TYPE_free(ret); 2094969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ret = NULL; 2104969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* Set point to start copying for modified encoding */ 2114969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin cpy_start = orig_der; 2124969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 2134969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* Do we need IMPLICIT tagging? */ 2144969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (asn1_tags.imp_tag != -1) { 2154969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* If IMPLICIT we will replace the underlying tag */ 2164969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* Skip existing tag+len */ 2174969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin r = ASN1_get_object(&cpy_start, &hdr_len, &hdr_tag, &hdr_class, 2184969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin cpy_len); 2194969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (r & 0x80) 2204969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin goto err; 2214969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* Update copy length */ 2224969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin cpy_len -= cpy_start - orig_der; 2234969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* 2244969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin * For IMPLICIT tagging the length should match the original length 2254969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin * and constructed flag should be consistent. 2264969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin */ 2274969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (r & 0x1) { 2284969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* Indefinite length constructed */ 2294969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin hdr_constructed = 2; 2304969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin hdr_len = 0; 2314969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } else 2324969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* Just retain constructed flag */ 2334969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin hdr_constructed = r & V_ASN1_CONSTRUCTED; 2344969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* 2354969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin * Work out new length with IMPLICIT tag: ignore constructed because 2364969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin * it will mess up if indefinite length 2374969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin */ 2384969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin len = ASN1_object_size(0, hdr_len, asn1_tags.imp_tag); 2394969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } else 2404969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin len = cpy_len; 2414969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 2424969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* Work out length in any EXPLICIT, starting from end */ 2434969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 2444969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin for (i = 0, etmp = asn1_tags.exp_list + asn1_tags.exp_count - 1; 2454969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin i < asn1_tags.exp_count; i++, etmp--) { 2464969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* Content length: number of content octets + any padding */ 2474969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin len += etmp->exp_pad; 2484969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin etmp->exp_len = len; 2494969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* Total object length: length including new header */ 2504969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin len = ASN1_object_size(0, len, etmp->exp_tag); 2514969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 2524969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 2534969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* Allocate buffer for new encoding */ 2544969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 2554969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin new_der = OPENSSL_malloc(len); 2564969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!new_der) 2574969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin goto err; 2584969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 2594969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* Generate tagged encoding */ 2604969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 2614969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin p = new_der; 2624969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 2634969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* Output explicit tags first */ 2644969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 2654969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin for (i = 0, etmp = asn1_tags.exp_list; i < asn1_tags.exp_count; 2664969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin i++, etmp++) { 2674969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_put_object(&p, etmp->exp_constructed, etmp->exp_len, 2684969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin etmp->exp_tag, etmp->exp_class); 2694969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (etmp->exp_pad) 2704969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin *p++ = 0; 2714969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 2724969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 2734969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* If IMPLICIT, output tag */ 2744969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 2754969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (asn1_tags.imp_tag != -1) { 2764969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (asn1_tags.imp_class == V_ASN1_UNIVERSAL 2774969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin && (asn1_tags.imp_tag == V_ASN1_SEQUENCE 2784969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin || asn1_tags.imp_tag == V_ASN1_SET)) 2794969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin hdr_constructed = V_ASN1_CONSTRUCTED; 2804969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_put_object(&p, hdr_constructed, hdr_len, 2814969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin asn1_tags.imp_tag, asn1_tags.imp_class); 2824969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 2834969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 2844969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* Copy across original encoding */ 28569939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan OPENSSL_memcpy(p, cpy_start, cpy_len); 2864969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 2874969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin cp = new_der; 2884969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 2894969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* Obtain new ASN1_TYPE structure */ 2904969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ret = d2i_ASN1_TYPE(NULL, &cp, len); 2914969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 2924969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin err: 2934969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (orig_der) 2944969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin OPENSSL_free(orig_der); 2954969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (new_der) 2964969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin OPENSSL_free(new_der); 2974969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 2984969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return ret; 2994969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 3004969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin} 301d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 302d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int asn1_cb(const char *elem, int len, void *bitstr) 3034969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin{ 3044969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin tag_exp_arg *arg = bitstr; 3054969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin int i; 3064969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin int utype; 3074969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin int vlen = 0; 3084969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin const char *p, *vstart = NULL; 3094969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 3104969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin int tmp_tag, tmp_class; 3114969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 3124969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (elem == NULL) 313f6200e70eccb73d7a8a6940d081918f5a2b98fadRobert Sloan return -1; 3144969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 3154969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin for (i = 0, p = elem; i < len; p++, i++) { 3164969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* Look for the ':' in name value pairs */ 3174969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (*p == ':') { 3184969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin vstart = p + 1; 3194969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin vlen = len - (vstart - elem); 3204969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin len = p - elem; 3214969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin break; 3224969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 3234969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 3244969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 3254969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin utype = asn1_str2tag(elem, len); 3264969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 3274969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (utype == -1) { 3284969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_TAG); 3294969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ERR_add_error_data(2, "tag=", elem); 3304969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return -1; 3314969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 3324969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 3334969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* If this is not a modifier mark end of string and exit */ 3344969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!(utype & ASN1_GEN_FLAG)) { 3354969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin arg->utype = utype; 3364969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin arg->str = vstart; 3374969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* If no value and not end of string, error */ 3384969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!vstart && elem[len]) { 3394969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_VALUE); 3404969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return -1; 3414969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 3424969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return 0; 3434969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 3444969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 3454969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin switch (utype) { 3464969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 3474969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin case ASN1_GEN_FLAG_IMP: 3484969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* Check for illegal multiple IMPLICIT tagging */ 3494969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (arg->imp_tag != -1) { 3504969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NESTED_TAGGING); 3514969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return -1; 3524969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 3534969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!parse_tagging(vstart, vlen, &arg->imp_tag, &arg->imp_class)) 3544969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return -1; 3554969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin break; 3564969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 3574969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin case ASN1_GEN_FLAG_EXP: 3584969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 3594969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!parse_tagging(vstart, vlen, &tmp_tag, &tmp_class)) 3604969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return -1; 3614969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!append_exp(arg, tmp_tag, tmp_class, 1, 0, 0)) 3624969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return -1; 3634969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin break; 3644969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 3654969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin case ASN1_GEN_FLAG_SEQWRAP: 3664969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!append_exp(arg, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, 1, 0, 1)) 3674969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return -1; 3684969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin break; 3694969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 3704969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin case ASN1_GEN_FLAG_SETWRAP: 3714969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!append_exp(arg, V_ASN1_SET, V_ASN1_UNIVERSAL, 1, 0, 1)) 3724969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return -1; 3734969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin break; 3744969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 3754969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin case ASN1_GEN_FLAG_BITWRAP: 3764969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!append_exp(arg, V_ASN1_BIT_STRING, V_ASN1_UNIVERSAL, 0, 1, 1)) 3774969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return -1; 3784969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin break; 3794969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 3804969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin case ASN1_GEN_FLAG_OCTWRAP: 3814969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!append_exp(arg, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL, 0, 0, 1)) 3824969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return -1; 3834969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin break; 3844969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 3854969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin case ASN1_GEN_FLAG_FORMAT: 3864969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!vstart) { 3874969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_FORMAT); 3884969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return -1; 3894969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 3904969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!strncmp(vstart, "ASCII", 5)) 3914969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin arg->format = ASN1_GEN_FORMAT_ASCII; 3924969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin else if (!strncmp(vstart, "UTF8", 4)) 3934969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin arg->format = ASN1_GEN_FORMAT_UTF8; 3944969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin else if (!strncmp(vstart, "HEX", 3)) 3954969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin arg->format = ASN1_GEN_FORMAT_HEX; 3964969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin else if (!strncmp(vstart, "BITLIST", 7)) 3974969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin arg->format = ASN1_GEN_FORMAT_BITLIST; 3984969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin else { 3994969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_FORMAT); 4004969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return -1; 4014969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 4024969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin break; 4034969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 4044969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 4054969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 4064969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return 1; 4074969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 4084969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin} 409d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 410d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass) 4114969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin{ 4124969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin char erch[2]; 4134969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin long tag_num; 4144969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin char *eptr; 4154969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!vstart) 4164969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return 0; 4174969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin tag_num = strtoul(vstart, &eptr, 10); 4184969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* Check we haven't gone past max length: should be impossible */ 4194969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (eptr && *eptr && (eptr > vstart + vlen)) 4204969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return 0; 4214969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (tag_num < 0) { 4224969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_NUMBER); 4234969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return 0; 4244969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 4254969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin *ptag = tag_num; 4264969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* If we have non numeric characters, parse them */ 4274969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (eptr) 4284969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin vlen -= eptr - vstart; 4294969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin else 4304969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin vlen = 0; 4314969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (vlen) { 4324969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin switch (*eptr) { 4334969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 4344969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin case 'U': 4354969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin *pclass = V_ASN1_UNIVERSAL; 4364969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin break; 4374969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 4384969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin case 'A': 4394969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin *pclass = V_ASN1_APPLICATION; 4404969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin break; 4414969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 4424969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin case 'P': 4434969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin *pclass = V_ASN1_PRIVATE; 4444969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin break; 4454969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 4464969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin case 'C': 4474969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin *pclass = V_ASN1_CONTEXT_SPECIFIC; 4484969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin break; 4494969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 4504969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin default: 4514969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin erch[0] = *eptr; 4524969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin erch[1] = 0; 4534969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_MODIFIER); 4544969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ERR_add_error_data(2, "Char=", erch); 4554969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return 0; 4564969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin break; 4574969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 4584969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 4594969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } else 4604969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin *pclass = V_ASN1_CONTEXT_SPECIFIC; 4614969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 4624969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return 1; 4634969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 4644969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin} 465d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 466d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* Handle multiple types: SET and SEQUENCE */ 467d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 468f6200e70eccb73d7a8a6940d081918f5a2b98fadRobert Sloanstatic ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf, 469f6200e70eccb73d7a8a6940d081918f5a2b98fadRobert Sloan int depth, int *perr) 4704969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin{ 4714969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_TYPE *ret = NULL; 4724969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin STACK_OF(ASN1_TYPE) *sk = NULL; 4734969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin STACK_OF(CONF_VALUE) *sect = NULL; 4744969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin unsigned char *der = NULL; 4754969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin int derlen; 4764969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin size_t i; 4774969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin sk = sk_ASN1_TYPE_new_null(); 4784969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!sk) 4794969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin goto bad; 4804969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (section) { 4814969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!cnf) 4824969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin goto bad; 4834969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin sect = X509V3_get_section(cnf, (char *)section); 4844969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!sect) 4854969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin goto bad; 4864969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin for (i = 0; i < sk_CONF_VALUE_num(sect); i++) { 4874969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_TYPE *typ = 488f6200e70eccb73d7a8a6940d081918f5a2b98fadRobert Sloan generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf, 489f6200e70eccb73d7a8a6940d081918f5a2b98fadRobert Sloan depth + 1, perr); 4904969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!typ) 4914969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin goto bad; 4924969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!sk_ASN1_TYPE_push(sk, typ)) 4934969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin goto bad; 4944969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 4954969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 4964969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 4974969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* 4984969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin * Now we has a STACK of the components, convert to the correct form 4994969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin */ 5004969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 5014969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (utype == V_ASN1_SET) 5024969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin derlen = i2d_ASN1_SET_ANY(sk, &der); 5034969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin else 5044969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin derlen = i2d_ASN1_SEQUENCE_ANY(sk, &der); 5054969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 5064969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (derlen < 0) 5074969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin goto bad; 5084969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 5094969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!(ret = ASN1_TYPE_new())) 5104969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin goto bad; 5114969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 5124969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!(ret->value.asn1_string = ASN1_STRING_type_new(utype))) 5134969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin goto bad; 5144969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 5154969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ret->type = utype; 5164969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 5174969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ret->value.asn1_string->data = der; 5184969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ret->value.asn1_string->length = derlen; 5194969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 5204969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin der = NULL; 5214969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 5224969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin bad: 5234969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 5244969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (der) 5254969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin OPENSSL_free(der); 5264969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 5274969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (sk) 5284969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free); 5294969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (sect) 5304969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin X509V3_section_free(cnf, sect); 5314969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 5324969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return ret; 5334969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin} 5344969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 5354969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjaminstatic int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, 5364969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin int exp_constructed, int exp_pad, int imp_ok) 5374969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin{ 5384969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin tag_exp_type *exp_tmp; 5394969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* Can only have IMPLICIT if permitted */ 5404969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if ((arg->imp_tag != -1) && !imp_ok) { 5414969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_IMPLICIT_TAG); 5424969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return 0; 5434969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 5444969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 5454969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (arg->exp_count == ASN1_FLAG_EXP_MAX) { 5464969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin OPENSSL_PUT_ERROR(ASN1, ASN1_R_DEPTH_EXCEEDED); 5474969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return 0; 5484969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 5494969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 5504969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin exp_tmp = &arg->exp_list[arg->exp_count++]; 5514969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 5524969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* 5534969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin * If IMPLICIT set tag to implicit value then reset implicit tag since it 5544969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin * has been used. 5554969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin */ 5564969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (arg->imp_tag != -1) { 5574969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin exp_tmp->exp_tag = arg->imp_tag; 5584969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin exp_tmp->exp_class = arg->imp_class; 5594969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin arg->imp_tag = -1; 5604969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin arg->imp_class = -1; 5614969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } else { 5624969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin exp_tmp->exp_tag = exp_tag; 5634969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin exp_tmp->exp_class = exp_class; 5644969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 5654969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin exp_tmp->exp_constructed = exp_constructed; 5664969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin exp_tmp->exp_pad = exp_pad; 5674969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 5684969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return 1; 5694969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin} 570d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 571d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int asn1_str2tag(const char *tagstr, int len) 5724969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin{ 5734969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin unsigned int i; 5744969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin static const struct tag_name_st *tntmp, tnst[] = { 5754969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("BOOL", V_ASN1_BOOLEAN), 5764969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("BOOLEAN", V_ASN1_BOOLEAN), 5774969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("NULL", V_ASN1_NULL), 5784969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("INT", V_ASN1_INTEGER), 5794969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("INTEGER", V_ASN1_INTEGER), 5804969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("ENUM", V_ASN1_ENUMERATED), 5814969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("ENUMERATED", V_ASN1_ENUMERATED), 5824969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("OID", V_ASN1_OBJECT), 5834969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("OBJECT", V_ASN1_OBJECT), 5844969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("UTCTIME", V_ASN1_UTCTIME), 5854969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("UTC", V_ASN1_UTCTIME), 5864969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("GENERALIZEDTIME", V_ASN1_GENERALIZEDTIME), 5874969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("GENTIME", V_ASN1_GENERALIZEDTIME), 5884969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("OCT", V_ASN1_OCTET_STRING), 5894969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("OCTETSTRING", V_ASN1_OCTET_STRING), 5904969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("BITSTR", V_ASN1_BIT_STRING), 5914969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("BITSTRING", V_ASN1_BIT_STRING), 5924969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("UNIVERSALSTRING", V_ASN1_UNIVERSALSTRING), 5934969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("UNIV", V_ASN1_UNIVERSALSTRING), 5944969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("IA5", V_ASN1_IA5STRING), 5954969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("IA5STRING", V_ASN1_IA5STRING), 5964969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("UTF8", V_ASN1_UTF8STRING), 5974969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("UTF8String", V_ASN1_UTF8STRING), 5984969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("BMP", V_ASN1_BMPSTRING), 5994969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("BMPSTRING", V_ASN1_BMPSTRING), 6004969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("VISIBLESTRING", V_ASN1_VISIBLESTRING), 6014969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("VISIBLE", V_ASN1_VISIBLESTRING), 6024969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("PRINTABLESTRING", V_ASN1_PRINTABLESTRING), 6034969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("PRINTABLE", V_ASN1_PRINTABLESTRING), 6044969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("T61", V_ASN1_T61STRING), 6054969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("T61STRING", V_ASN1_T61STRING), 6064969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("TELETEXSTRING", V_ASN1_T61STRING), 6074969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("GeneralString", V_ASN1_GENERALSTRING), 6084969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("GENSTR", V_ASN1_GENERALSTRING), 6094969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("NUMERIC", V_ASN1_NUMERICSTRING), 6104969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("NUMERICSTRING", V_ASN1_NUMERICSTRING), 6114969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 6124969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* Special cases */ 6134969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("SEQUENCE", V_ASN1_SEQUENCE), 6144969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("SEQ", V_ASN1_SEQUENCE), 6154969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("SET", V_ASN1_SET), 6164969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* type modifiers */ 6174969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* Explicit tag */ 6184969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("EXP", ASN1_GEN_FLAG_EXP), 6194969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("EXPLICIT", ASN1_GEN_FLAG_EXP), 6204969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* Implicit tag */ 6214969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("IMP", ASN1_GEN_FLAG_IMP), 6224969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("IMPLICIT", ASN1_GEN_FLAG_IMP), 6234969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* OCTET STRING wrapper */ 6244969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("OCTWRAP", ASN1_GEN_FLAG_OCTWRAP), 6254969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* SEQUENCE wrapper */ 6264969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("SEQWRAP", ASN1_GEN_FLAG_SEQWRAP), 6274969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* SET wrapper */ 6284969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("SETWRAP", ASN1_GEN_FLAG_SETWRAP), 6294969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* BIT STRING wrapper */ 6304969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("BITWRAP", ASN1_GEN_FLAG_BITWRAP), 6314969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("FORM", ASN1_GEN_FLAG_FORMAT), 6324969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_GEN_STR("FORMAT", ASN1_GEN_FLAG_FORMAT), 6334969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin }; 6344969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 6354969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (len == -1) 6364969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin len = strlen(tagstr); 6374969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 6384969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin tntmp = tnst; 6394969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin for (i = 0; i < sizeof(tnst) / sizeof(struct tag_name_st); i++, tntmp++) { 6404969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if ((len == tntmp->len) && !strncmp(tntmp->strnam, tagstr, len)) 6414969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return tntmp->tag; 6424969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 6434969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 6444969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return -1; 6454969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin} 646d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 647d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic ASN1_TYPE *asn1_str2type(const char *str, int format, int utype) 6484969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin{ 6494969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_TYPE *atmp = NULL; 6504969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 6514969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin CONF_VALUE vtmp; 6524969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 6534969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin unsigned char *rdata; 6544969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin long rdlen; 6554969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 6564969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin int no_unused = 1; 6574969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 6584969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!(atmp = ASN1_TYPE_new())) { 6594969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); 6604969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return NULL; 6614969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 6624969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 6634969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!str) 6644969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin str = ""; 6654969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 6664969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin switch (utype) { 6674969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 6684969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin case V_ASN1_NULL: 6694969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (str && *str) { 6704969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NULL_VALUE); 6714969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin goto bad_form; 6724969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 6734969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin break; 6744969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 6754969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin case V_ASN1_BOOLEAN: 6764969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (format != ASN1_GEN_FORMAT_ASCII) { 6774969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ASCII_FORMAT); 6784969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin goto bad_form; 6794969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 6804969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin vtmp.name = NULL; 6814969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin vtmp.section = NULL; 6824969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin vtmp.value = (char *)str; 6834969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!X509V3_get_value_bool(&vtmp, &atmp->value.boolean)) { 6844969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_BOOLEAN); 6854969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin goto bad_str; 6864969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 6874969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin break; 6884969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 6894969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin case V_ASN1_INTEGER: 6904969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin case V_ASN1_ENUMERATED: 6914969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (format != ASN1_GEN_FORMAT_ASCII) { 6924969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin OPENSSL_PUT_ERROR(ASN1, ASN1_R_INTEGER_NOT_ASCII_FORMAT); 6934969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin goto bad_form; 6944969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 6954969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!(atmp->value.integer = s2i_ASN1_INTEGER(NULL, (char *)str))) { 6964969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_INTEGER); 6974969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin goto bad_str; 6984969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 6994969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin break; 7004969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 7014969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin case V_ASN1_OBJECT: 7024969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (format != ASN1_GEN_FORMAT_ASCII) { 7034969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin OPENSSL_PUT_ERROR(ASN1, ASN1_R_OBJECT_NOT_ASCII_FORMAT); 7044969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin goto bad_form; 7054969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 7064969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!(atmp->value.object = OBJ_txt2obj(str, 0))) { 7074969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OBJECT); 7084969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin goto bad_str; 7094969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 7104969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin break; 7114969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 7124969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin case V_ASN1_UTCTIME: 7134969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin case V_ASN1_GENERALIZEDTIME: 7144969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (format != ASN1_GEN_FORMAT_ASCII) { 7154969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin OPENSSL_PUT_ERROR(ASN1, ASN1_R_TIME_NOT_ASCII_FORMAT); 7164969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin goto bad_form; 7174969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 7184969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!(atmp->value.asn1_string = ASN1_STRING_new())) { 7194969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); 7204969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin goto bad_str; 7214969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 7224969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1)) { 7234969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); 7244969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin goto bad_str; 7254969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 7264969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin atmp->value.asn1_string->type = utype; 7274969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!ASN1_TIME_check(atmp->value.asn1_string)) { 7284969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_TIME_VALUE); 7294969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin goto bad_str; 7304969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 7314969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 7324969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin break; 7334969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 7344969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin case V_ASN1_BMPSTRING: 7354969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin case V_ASN1_PRINTABLESTRING: 7364969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin case V_ASN1_IA5STRING: 7374969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin case V_ASN1_T61STRING: 7384969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin case V_ASN1_UTF8STRING: 7394969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin case V_ASN1_VISIBLESTRING: 7404969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin case V_ASN1_UNIVERSALSTRING: 7414969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin case V_ASN1_GENERALSTRING: 7424969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin case V_ASN1_NUMERICSTRING: 7434969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 7444969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (format == ASN1_GEN_FORMAT_ASCII) 7454969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin format = MBSTRING_ASC; 7464969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin else if (format == ASN1_GEN_FORMAT_UTF8) 7474969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin format = MBSTRING_UTF8; 7484969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin else { 7494969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_FORMAT); 7504969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin goto bad_form; 7514969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 7524969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 7534969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (ASN1_mbstring_copy(&atmp->value.asn1_string, (unsigned char *)str, 7544969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin -1, format, ASN1_tag2bit(utype)) <= 0) { 7554969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); 7564969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin goto bad_str; 7574969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 7584969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 7594969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin break; 7604969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 7614969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin case V_ASN1_BIT_STRING: 7624969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 7634969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin case V_ASN1_OCTET_STRING: 7644969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 7654969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!(atmp->value.asn1_string = ASN1_STRING_new())) { 7664969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); 7674969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin goto bad_form; 7684969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 7694969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 7704969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (format == ASN1_GEN_FORMAT_HEX) { 7714969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 7724969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!(rdata = string_to_hex((char *)str, &rdlen))) { 7734969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_HEX); 7744969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin goto bad_str; 7754969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 7764969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 7774969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin atmp->value.asn1_string->data = rdata; 7784969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin atmp->value.asn1_string->length = rdlen; 7794969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin atmp->value.asn1_string->type = utype; 7804969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 7814969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } else if (format == ASN1_GEN_FORMAT_ASCII) 7824969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_STRING_set(atmp->value.asn1_string, str, -1); 7834969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin else if ((format == ASN1_GEN_FORMAT_BITLIST) 7844969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin && (utype == V_ASN1_BIT_STRING)) { 7854969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!CONF_parse_list 7864969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin (str, ',', 1, bitstr_cb, atmp->value.bit_string)) { 7874969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin OPENSSL_PUT_ERROR(ASN1, ASN1_R_LIST_ERROR); 7884969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin goto bad_str; 7894969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 7904969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin no_unused = 0; 7914969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 7924969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } else { 7934969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_BITSTRING_FORMAT); 7944969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin goto bad_form; 7954969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 7964969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 7974969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if ((utype == V_ASN1_BIT_STRING) && no_unused) { 7984969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin atmp->value.asn1_string->flags 7994969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); 8004969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin atmp->value.asn1_string->flags |= ASN1_STRING_FLAG_BITS_LEFT; 8014969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 8024969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 8034969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin break; 8044969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 8054969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin default: 8064969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNSUPPORTED_TYPE); 8074969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin goto bad_str; 8084969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin break; 8094969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 8104969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 8114969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin atmp->type = utype; 8124969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return atmp; 8134969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 8144969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin bad_str: 8154969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ERR_add_error_data(2, "string=", str); 8164969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin bad_form: 8174969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 8184969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_TYPE_free(atmp); 8194969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return NULL; 8204969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 8214969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin} 822d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 823d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int bitstr_cb(const char *elem, int len, void *bitstr) 8244969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin{ 8254969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin long bitnum; 8264969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin char *eptr; 8274969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!elem) 8284969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return 0; 8294969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin bitnum = strtoul(elem, &eptr, 10); 8304969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (eptr && *eptr && (eptr != elem + len)) 8314969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return 0; 8324969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (bitnum < 0) { 8334969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_NUMBER); 8344969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return 0; 8354969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 8364969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!ASN1_BIT_STRING_set_bit(bitstr, bitnum, 1)) { 8374969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); 8384969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return 0; 8394969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 8404969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return 1; 8414969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin} 842