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