155714Skris/* crypto/asn1/t_req.c */
255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
355714Skris * All rights reserved.
455714Skris *
555714Skris * This package is an SSL implementation written
655714Skris * by Eric Young (eay@cryptsoft.com).
755714Skris * The implementation was written so as to conform with Netscapes SSL.
8296341Sdelphij *
955714Skris * This library is free for commercial and non-commercial use as long as
1055714Skris * the following conditions are aheared to.  The following conditions
1155714Skris * apply to all code found in this distribution, be it the RC4, RSA,
1255714Skris * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1355714Skris * included with this distribution is covered by the same copyright terms
1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15296341Sdelphij *
1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in
1755714Skris * the code are not to be removed.
1855714Skris * If this package is used in a product, Eric Young should be given attribution
1955714Skris * as the author of the parts of the library used.
2055714Skris * This can be in the form of a textual message at program startup or
2155714Skris * in documentation (online or textual) provided with the package.
22296341Sdelphij *
2355714Skris * Redistribution and use in source and binary forms, with or without
2455714Skris * modification, are permitted provided that the following conditions
2555714Skris * are met:
2655714Skris * 1. Redistributions of source code must retain the copyright
2755714Skris *    notice, this list of conditions and the following disclaimer.
2855714Skris * 2. Redistributions in binary form must reproduce the above copyright
2955714Skris *    notice, this list of conditions and the following disclaimer in the
3055714Skris *    documentation and/or other materials provided with the distribution.
3155714Skris * 3. All advertising materials mentioning features or use of this software
3255714Skris *    must display the following acknowledgement:
3355714Skris *    "This product includes cryptographic software written by
3455714Skris *     Eric Young (eay@cryptsoft.com)"
3555714Skris *    The word 'cryptographic' can be left out if the rouines from the library
3655714Skris *    being used are not cryptographic related :-).
37296341Sdelphij * 4. If you include any Windows specific code (or a derivative thereof) from
3855714Skris *    the apps directory (application code) you must include an acknowledgement:
3955714Skris *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40296341Sdelphij *
4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4455714Skris * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5155714Skris * SUCH DAMAGE.
52296341Sdelphij *
5355714Skris * The licence and distribution terms for any publically available version or
5455714Skris * derivative of this code cannot be changed.  i.e. this code cannot simply be
5555714Skris * copied and put under another distribution licence
5655714Skris * [including the GNU Public Licence.]
5755714Skris */
5855714Skris
5955714Skris#include <stdio.h>
6055714Skris#include "cryptlib.h"
6155714Skris#include <openssl/buffer.h>
6255714Skris#include <openssl/bn.h>
6355714Skris#include <openssl/objects.h>
6455714Skris#include <openssl/x509.h>
6559191Skris#include <openssl/x509v3.h>
66160814Ssimon#ifndef OPENSSL_NO_RSA
67296341Sdelphij# include <openssl/rsa.h>
68160814Ssimon#endif
69160814Ssimon#ifndef OPENSSL_NO_DSA
70296341Sdelphij# include <openssl/dsa.h>
71160814Ssimon#endif
7255714Skris
73109998Smarkm#ifndef OPENSSL_NO_FP_API
7455714Skrisint X509_REQ_print_fp(FILE *fp, X509_REQ *x)
75296341Sdelphij{
76296341Sdelphij    BIO *b;
77296341Sdelphij    int ret;
7855714Skris
79296341Sdelphij    if ((b = BIO_new(BIO_s_file())) == NULL) {
80296341Sdelphij        X509err(X509_F_X509_REQ_PRINT_FP, ERR_R_BUF_LIB);
81296341Sdelphij        return (0);
82296341Sdelphij    }
83296341Sdelphij    BIO_set_fp(b, fp, BIO_NOCLOSE);
84296341Sdelphij    ret = X509_REQ_print(b, x);
85296341Sdelphij    BIO_free(b);
86296341Sdelphij    return (ret);
87296341Sdelphij}
8855714Skris#endif
8955714Skris
90296341Sdelphijint X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags,
91296341Sdelphij                      unsigned long cflag)
92296341Sdelphij{
93296341Sdelphij    unsigned long l;
94296341Sdelphij    int i;
95296341Sdelphij    const char *neg;
96296341Sdelphij    X509_REQ_INFO *ri;
97296341Sdelphij    EVP_PKEY *pkey;
98296341Sdelphij    STACK_OF(X509_ATTRIBUTE) *sk;
99296341Sdelphij    STACK_OF(X509_EXTENSION) *exts;
100296341Sdelphij    char mlch = ' ';
101296341Sdelphij    int nmindent = 0;
10255714Skris
103296341Sdelphij    if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
104296341Sdelphij        mlch = '\n';
105296341Sdelphij        nmindent = 12;
106296341Sdelphij    }
10755714Skris
108296341Sdelphij    if (nmflags == X509_FLAG_COMPAT)
109296341Sdelphij        nmindent = 16;
11055714Skris
111296341Sdelphij    ri = x->req_info;
112296341Sdelphij    if (!(cflag & X509_FLAG_NO_HEADER)) {
113296341Sdelphij        if (BIO_write(bp, "Certificate Request:\n", 21) <= 0)
114296341Sdelphij            goto err;
115296341Sdelphij        if (BIO_write(bp, "    Data:\n", 10) <= 0)
116296341Sdelphij            goto err;
117296341Sdelphij    }
118296341Sdelphij    if (!(cflag & X509_FLAG_NO_VERSION)) {
119296341Sdelphij        neg = (ri->version->type == V_ASN1_NEG_INTEGER) ? "-" : "";
120296341Sdelphij        l = 0;
121296341Sdelphij        for (i = 0; i < ri->version->length; i++) {
122296341Sdelphij            l <<= 8;
123296341Sdelphij            l += ri->version->data[i];
124296341Sdelphij        }
125296341Sdelphij        if (BIO_printf(bp, "%8sVersion: %s%lu (%s0x%lx)\n", "", neg, l, neg,
126296341Sdelphij                       l) <= 0)
127296341Sdelphij            goto err;
128296341Sdelphij    }
129296341Sdelphij    if (!(cflag & X509_FLAG_NO_SUBJECT)) {
130296341Sdelphij        if (BIO_printf(bp, "        Subject:%c", mlch) <= 0)
131296341Sdelphij            goto err;
132296341Sdelphij        if (X509_NAME_print_ex(bp, ri->subject, nmindent, nmflags) < 0)
133296341Sdelphij            goto err;
134296341Sdelphij        if (BIO_write(bp, "\n", 1) <= 0)
135296341Sdelphij            goto err;
136296341Sdelphij    }
137296341Sdelphij    if (!(cflag & X509_FLAG_NO_PUBKEY)) {
138296341Sdelphij        if (BIO_write(bp, "        Subject Public Key Info:\n", 33) <= 0)
139296341Sdelphij            goto err;
140296341Sdelphij        if (BIO_printf(bp, "%12sPublic Key Algorithm: ", "") <= 0)
141296341Sdelphij            goto err;
142296341Sdelphij        if (i2a_ASN1_OBJECT(bp, ri->pubkey->algor->algorithm) <= 0)
143296341Sdelphij            goto err;
144296341Sdelphij        if (BIO_puts(bp, "\n") <= 0)
145296341Sdelphij            goto err;
14655714Skris
147296341Sdelphij        pkey = X509_REQ_get_pubkey(x);
148296341Sdelphij        if (pkey == NULL) {
149296341Sdelphij            BIO_printf(bp, "%12sUnable to load Public Key\n", "");
150296341Sdelphij            ERR_print_errors(bp);
151296341Sdelphij        } else {
152296341Sdelphij            EVP_PKEY_print_public(bp, pkey, 16, NULL);
153296341Sdelphij            EVP_PKEY_free(pkey);
154296341Sdelphij        }
155296341Sdelphij    }
156109998Smarkm
157296341Sdelphij    if (!(cflag & X509_FLAG_NO_ATTRIBUTES)) {
158296341Sdelphij        /* may not be */
159296341Sdelphij        if (BIO_printf(bp, "%8sAttributes:\n", "") <= 0)
160296341Sdelphij            goto err;
16155714Skris
162296341Sdelphij        sk = x->req_info->attributes;
163296341Sdelphij        if (sk_X509_ATTRIBUTE_num(sk) == 0) {
164296341Sdelphij            if (BIO_printf(bp, "%12sa0:00\n", "") <= 0)
165296341Sdelphij                goto err;
166296341Sdelphij        } else {
167296341Sdelphij            for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) {
168296341Sdelphij                ASN1_TYPE *at;
169296341Sdelphij                X509_ATTRIBUTE *a;
170296341Sdelphij                ASN1_BIT_STRING *bs = NULL;
171296341Sdelphij                ASN1_TYPE *t;
172296341Sdelphij                int j, type = 0, count = 1, ii = 0;
17355714Skris
174296341Sdelphij                a = sk_X509_ATTRIBUTE_value(sk, i);
175296341Sdelphij                if (X509_REQ_extension_nid(OBJ_obj2nid(a->object)))
176296341Sdelphij                    continue;
177296341Sdelphij                if (BIO_printf(bp, "%12s", "") <= 0)
178296341Sdelphij                    goto err;
179296341Sdelphij                if ((j = i2a_ASN1_OBJECT(bp, a->object)) > 0) {
180296341Sdelphij                    if (a->single) {
181296341Sdelphij                        t = a->value.single;
182296341Sdelphij                        type = t->type;
183296341Sdelphij                        bs = t->value.bit_string;
184296341Sdelphij                    } else {
185296341Sdelphij                        ii = 0;
186296341Sdelphij                        count = sk_ASN1_TYPE_num(a->value.set);
187296341Sdelphij get_next:
188296341Sdelphij                        at = sk_ASN1_TYPE_value(a->value.set, ii);
189296341Sdelphij                        type = at->type;
190296341Sdelphij                        bs = at->value.asn1_string;
191296341Sdelphij                    }
192296341Sdelphij                }
193296341Sdelphij                for (j = 25 - j; j > 0; j--)
194296341Sdelphij                    if (BIO_write(bp, " ", 1) != 1)
195296341Sdelphij                        goto err;
196296341Sdelphij                if (BIO_puts(bp, ":") <= 0)
197296341Sdelphij                    goto err;
198296341Sdelphij                if ((type == V_ASN1_PRINTABLESTRING) ||
199296341Sdelphij                    (type == V_ASN1_T61STRING) ||
200296341Sdelphij                    (type == V_ASN1_IA5STRING)) {
201296341Sdelphij                    if (BIO_write(bp, (char *)bs->data, bs->length)
202296341Sdelphij                        != bs->length)
203296341Sdelphij                        goto err;
204296341Sdelphij                    BIO_puts(bp, "\n");
205296341Sdelphij                } else {
206296341Sdelphij                    BIO_puts(bp, "unable to print attribute\n");
207296341Sdelphij                }
208296341Sdelphij                if (++ii < count)
209296341Sdelphij                    goto get_next;
210296341Sdelphij            }
211296341Sdelphij        }
212296341Sdelphij    }
213296341Sdelphij    if (!(cflag & X509_FLAG_NO_EXTENSIONS)) {
214296341Sdelphij        exts = X509_REQ_get_extensions(x);
215296341Sdelphij        if (exts) {
216296341Sdelphij            BIO_printf(bp, "%8sRequested Extensions:\n", "");
217296341Sdelphij            for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
218296341Sdelphij                ASN1_OBJECT *obj;
219296341Sdelphij                X509_EXTENSION *ex;
220296341Sdelphij                int j;
221296341Sdelphij                ex = sk_X509_EXTENSION_value(exts, i);
222296341Sdelphij                if (BIO_printf(bp, "%12s", "") <= 0)
223296341Sdelphij                    goto err;
224296341Sdelphij                obj = X509_EXTENSION_get_object(ex);
225296341Sdelphij                i2a_ASN1_OBJECT(bp, obj);
226296341Sdelphij                j = X509_EXTENSION_get_critical(ex);
227296341Sdelphij                if (BIO_printf(bp, ": %s\n", j ? "critical" : "") <= 0)
228296341Sdelphij                    goto err;
229296341Sdelphij                if (!X509V3_EXT_print(bp, ex, cflag, 16)) {
230296341Sdelphij                    BIO_printf(bp, "%16s", "");
231296341Sdelphij                    M_ASN1_OCTET_STRING_print(bp, ex->value);
232296341Sdelphij                }
233296341Sdelphij                if (BIO_write(bp, "\n", 1) <= 0)
234296341Sdelphij                    goto err;
235296341Sdelphij            }
236296341Sdelphij            sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
237296341Sdelphij        }
238296341Sdelphij    }
23955714Skris
240296341Sdelphij    if (!(cflag & X509_FLAG_NO_SIGDUMP)) {
241296341Sdelphij        if (!X509_signature_print(bp, x->sig_alg, x->signature))
242296341Sdelphij            goto err;
243296341Sdelphij    }
24455714Skris
245296341Sdelphij    return (1);
246296341Sdelphij err:
247296341Sdelphij    X509err(X509_F_X509_REQ_PRINT_EX, ERR_R_BUF_LIB);
248296341Sdelphij    return (0);
249296341Sdelphij}
25059191Skris
251109998Smarkmint X509_REQ_print(BIO *bp, X509_REQ *x)
252296341Sdelphij{
253296341Sdelphij    return X509_REQ_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
254296341Sdelphij}
255