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/mem.h> 63d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/obj.h> 64d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 65d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include "charmap.h" 66d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 67d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 68d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* ASN1_STRING_print_ex() and X509_NAME_print_ex(). 69d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Enhanced string and name printing routines handling 70d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * multibyte characters, RFC2253 and a host of other 71d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * options. 72d9e397b599b13d642138480a28c14db7a136bf0Adam Langley */ 73d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 74d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 75d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#define CHARTYPE_BS_ESC (ASN1_STRFLGS_ESC_2253 | CHARTYPE_FIRST_ESC_2253 | CHARTYPE_LAST_ESC_2253) 76d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 77d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#define ESC_FLAGS (ASN1_STRFLGS_ESC_2253 | \ 78d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ASN1_STRFLGS_ESC_QUOTE | \ 79d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ASN1_STRFLGS_ESC_CTRL | \ 80d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ASN1_STRFLGS_ESC_MSB) 81d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 82d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 83d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int send_bio_chars(void *arg, const void *buf, int len) 84d9e397b599b13d642138480a28c14db7a136bf0Adam Langley{ 85d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(!arg) return 1; 86d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(BIO_write(arg, buf, len) != len) return 0; 87d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 1; 88d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 89d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 90d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int send_fp_chars(void *arg, const void *buf, int len) 91d9e397b599b13d642138480a28c14db7a136bf0Adam Langley{ 92d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(!arg) return 1; 93d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(fwrite(buf, 1, len, arg) != (unsigned int)len) return 0; 94d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 1; 95d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 96d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 97d9e397b599b13d642138480a28c14db7a136bf0Adam Langleytypedef int char_io(void *arg, const void *buf, int len); 98d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 99d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* This function handles display of 100d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * strings, one character at a time. 101d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * It is passed an unsigned long for each 102d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * character because it could come from 2 or even 103d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 4 byte forms. 104d9e397b599b13d642138480a28c14db7a136bf0Adam Langley */ 105d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 106d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#define HEX_SIZE(type) (sizeof(type)*2) 107d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 108d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int do_esc_char(unsigned long c, unsigned char flags, char *do_quotes, char_io *io_ch, void *arg) 109d9e397b599b13d642138480a28c14db7a136bf0Adam Langley{ 110d9e397b599b13d642138480a28c14db7a136bf0Adam Langley unsigned char chflgs, chtmp; 111d9e397b599b13d642138480a28c14db7a136bf0Adam Langley char tmphex[HEX_SIZE(long)+3]; 112d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 113d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(c > 0xffffffffL) 114d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return -1; 115d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(c > 0xffff) { 116d9e397b599b13d642138480a28c14db7a136bf0Adam Langley BIO_snprintf(tmphex, sizeof tmphex, "\\W%08lX", c); 117d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(!io_ch(arg, tmphex, 10)) return -1; 118d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 10; 119d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 120d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(c > 0xff) { 121d9e397b599b13d642138480a28c14db7a136bf0Adam Langley BIO_snprintf(tmphex, sizeof tmphex, "\\U%04lX", c); 122d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(!io_ch(arg, tmphex, 6)) return -1; 123d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 6; 124d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 125d9e397b599b13d642138480a28c14db7a136bf0Adam Langley chtmp = (unsigned char)c; 126d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(chtmp > 0x7f) chflgs = flags & ASN1_STRFLGS_ESC_MSB; 127d9e397b599b13d642138480a28c14db7a136bf0Adam Langley else chflgs = char_type[chtmp] & flags; 128d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(chflgs & CHARTYPE_BS_ESC) { 129d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* If we don't escape with quotes, signal we need quotes */ 130d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(chflgs & ASN1_STRFLGS_ESC_QUOTE) { 131d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(do_quotes) *do_quotes = 1; 132d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(!io_ch(arg, &chtmp, 1)) return -1; 133d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 1; 134d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 135d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(!io_ch(arg, "\\", 1)) return -1; 136d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(!io_ch(arg, &chtmp, 1)) return -1; 137d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 2; 138d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 139d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(chflgs & (ASN1_STRFLGS_ESC_CTRL|ASN1_STRFLGS_ESC_MSB)) { 140d9e397b599b13d642138480a28c14db7a136bf0Adam Langley BIO_snprintf(tmphex, 11, "\\%02X", chtmp); 141d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(!io_ch(arg, tmphex, 3)) return -1; 142d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 3; 143d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 144d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* If we get this far and do any escaping at all must escape 145d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * the escape character itself: backslash. 146d9e397b599b13d642138480a28c14db7a136bf0Adam Langley */ 147d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (chtmp == '\\' && flags & ESC_FLAGS) { 148d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(!io_ch(arg, "\\\\", 2)) return -1; 149d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 2; 150d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 151d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(!io_ch(arg, &chtmp, 1)) return -1; 152d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 1; 153d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 154d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 155d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#define BUF_TYPE_WIDTH_MASK 0x7 156d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#define BUF_TYPE_CONVUTF8 0x8 157d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 158d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* This function sends each character in a buffer to 159d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * do_esc_char(). It interprets the content formats 160d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * and converts to or from UTF8 as appropriate. 161d9e397b599b13d642138480a28c14db7a136bf0Adam Langley */ 162d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 163d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int do_buf(unsigned char *buf, int buflen, 164d9e397b599b13d642138480a28c14db7a136bf0Adam Langley int type, unsigned char flags, char *quotes, char_io *io_ch, void *arg) 165d9e397b599b13d642138480a28c14db7a136bf0Adam Langley{ 166d9e397b599b13d642138480a28c14db7a136bf0Adam Langley int i, outlen, len; 167d9e397b599b13d642138480a28c14db7a136bf0Adam Langley unsigned char orflags, *p, *q; 168d9e397b599b13d642138480a28c14db7a136bf0Adam Langley unsigned long c; 169d9e397b599b13d642138480a28c14db7a136bf0Adam Langley p = buf; 170d9e397b599b13d642138480a28c14db7a136bf0Adam Langley q = buf + buflen; 171d9e397b599b13d642138480a28c14db7a136bf0Adam Langley outlen = 0; 172d9e397b599b13d642138480a28c14db7a136bf0Adam Langley while(p != q) { 173d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(p == buf && flags & ASN1_STRFLGS_ESC_2253) orflags = CHARTYPE_FIRST_ESC_2253; 174d9e397b599b13d642138480a28c14db7a136bf0Adam Langley else orflags = 0; 175d9e397b599b13d642138480a28c14db7a136bf0Adam Langley switch(type & BUF_TYPE_WIDTH_MASK) { 176d9e397b599b13d642138480a28c14db7a136bf0Adam Langley case 4: 177d9e397b599b13d642138480a28c14db7a136bf0Adam Langley c = ((unsigned long)*p++) << 24; 178d9e397b599b13d642138480a28c14db7a136bf0Adam Langley c |= ((unsigned long)*p++) << 16; 179d9e397b599b13d642138480a28c14db7a136bf0Adam Langley c |= ((unsigned long)*p++) << 8; 180d9e397b599b13d642138480a28c14db7a136bf0Adam Langley c |= *p++; 181d9e397b599b13d642138480a28c14db7a136bf0Adam Langley break; 182d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 183d9e397b599b13d642138480a28c14db7a136bf0Adam Langley case 2: 184d9e397b599b13d642138480a28c14db7a136bf0Adam Langley c = ((unsigned long)*p++) << 8; 185d9e397b599b13d642138480a28c14db7a136bf0Adam Langley c |= *p++; 186d9e397b599b13d642138480a28c14db7a136bf0Adam Langley break; 187d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 188d9e397b599b13d642138480a28c14db7a136bf0Adam Langley case 1: 189d9e397b599b13d642138480a28c14db7a136bf0Adam Langley c = *p++; 190d9e397b599b13d642138480a28c14db7a136bf0Adam Langley break; 191d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 192d9e397b599b13d642138480a28c14db7a136bf0Adam Langley case 0: 193d9e397b599b13d642138480a28c14db7a136bf0Adam Langley i = UTF8_getc(p, buflen, &c); 194d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(i < 0) return -1; /* Invalid UTF8String */ 195d9e397b599b13d642138480a28c14db7a136bf0Adam Langley p += i; 196d9e397b599b13d642138480a28c14db7a136bf0Adam Langley break; 197d9e397b599b13d642138480a28c14db7a136bf0Adam Langley default: 198d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return -1; /* invalid width */ 199d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 200d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (p == q && flags & ASN1_STRFLGS_ESC_2253) orflags = CHARTYPE_LAST_ESC_2253; 201d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(type & BUF_TYPE_CONVUTF8) { 202d9e397b599b13d642138480a28c14db7a136bf0Adam Langley unsigned char utfbuf[6]; 203d9e397b599b13d642138480a28c14db7a136bf0Adam Langley int utflen; 204d9e397b599b13d642138480a28c14db7a136bf0Adam Langley utflen = UTF8_putc(utfbuf, sizeof utfbuf, c); 205d9e397b599b13d642138480a28c14db7a136bf0Adam Langley for(i = 0; i < utflen; i++) { 206d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* We don't need to worry about setting orflags correctly 207d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * because if utflen==1 its value will be correct anyway 208d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * otherwise each character will be > 0x7f and so the 209d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * character will never be escaped on first and last. 210d9e397b599b13d642138480a28c14db7a136bf0Adam Langley */ 211d9e397b599b13d642138480a28c14db7a136bf0Adam Langley len = do_esc_char(utfbuf[i], (unsigned char)(flags | orflags), quotes, io_ch, arg); 212d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(len < 0) return -1; 213d9e397b599b13d642138480a28c14db7a136bf0Adam Langley outlen += len; 214d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 215d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } else { 216d9e397b599b13d642138480a28c14db7a136bf0Adam Langley len = do_esc_char(c, (unsigned char)(flags | orflags), quotes, io_ch, arg); 217d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(len < 0) return -1; 218d9e397b599b13d642138480a28c14db7a136bf0Adam Langley outlen += len; 219d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 220d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 221d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return outlen; 222d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 223d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 224d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* This function hex dumps a buffer of characters */ 225d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 226d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int do_hex_dump(char_io *io_ch, void *arg, unsigned char *buf, int buflen) 227d9e397b599b13d642138480a28c14db7a136bf0Adam Langley{ 228d9e397b599b13d642138480a28c14db7a136bf0Adam Langley static const char hexdig[] = "0123456789ABCDEF"; 229d9e397b599b13d642138480a28c14db7a136bf0Adam Langley unsigned char *p, *q; 230d9e397b599b13d642138480a28c14db7a136bf0Adam Langley char hextmp[2]; 231d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(arg) { 232d9e397b599b13d642138480a28c14db7a136bf0Adam Langley p = buf; 233d9e397b599b13d642138480a28c14db7a136bf0Adam Langley q = buf + buflen; 234d9e397b599b13d642138480a28c14db7a136bf0Adam Langley while(p != q) { 235d9e397b599b13d642138480a28c14db7a136bf0Adam Langley hextmp[0] = hexdig[*p >> 4]; 236d9e397b599b13d642138480a28c14db7a136bf0Adam Langley hextmp[1] = hexdig[*p & 0xf]; 237d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(!io_ch(arg, hextmp, 2)) return -1; 238d9e397b599b13d642138480a28c14db7a136bf0Adam Langley p++; 239d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 240d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 241d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return buflen << 1; 242d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 243d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 244d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* "dump" a string. This is done when the type is unknown, 245d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * or the flags request it. We can either dump the content 246d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * octets or the entire DER encoding. This uses the RFC2253 247d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * #01234 format. 248d9e397b599b13d642138480a28c14db7a136bf0Adam Langley */ 249d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 250d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int do_dump(unsigned long lflags, char_io *io_ch, void *arg, ASN1_STRING *str) 251d9e397b599b13d642138480a28c14db7a136bf0Adam Langley{ 252d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* Placing the ASN1_STRING in a temp ASN1_TYPE allows 253d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * the DER encoding to readily obtained 254d9e397b599b13d642138480a28c14db7a136bf0Adam Langley */ 255d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ASN1_TYPE t; 256d9e397b599b13d642138480a28c14db7a136bf0Adam Langley unsigned char *der_buf, *p; 257d9e397b599b13d642138480a28c14db7a136bf0Adam Langley int outlen, der_len; 258d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 259d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(!io_ch(arg, "#", 1)) return -1; 260d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* If we don't dump DER encoding just dump content octets */ 261d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(!(lflags & ASN1_STRFLGS_DUMP_DER)) { 262d9e397b599b13d642138480a28c14db7a136bf0Adam Langley outlen = do_hex_dump(io_ch, arg, str->data, str->length); 263d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(outlen < 0) return -1; 264d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return outlen + 1; 265d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 266d9e397b599b13d642138480a28c14db7a136bf0Adam Langley t.type = str->type; 267d9e397b599b13d642138480a28c14db7a136bf0Adam Langley t.value.ptr = (char *)str; 268d9e397b599b13d642138480a28c14db7a136bf0Adam Langley der_len = i2d_ASN1_TYPE(&t, NULL); 269d9e397b599b13d642138480a28c14db7a136bf0Adam Langley der_buf = OPENSSL_malloc(der_len); 270d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(!der_buf) return -1; 271d9e397b599b13d642138480a28c14db7a136bf0Adam Langley p = der_buf; 272d9e397b599b13d642138480a28c14db7a136bf0Adam Langley i2d_ASN1_TYPE(&t, &p); 273d9e397b599b13d642138480a28c14db7a136bf0Adam Langley outlen = do_hex_dump(io_ch, arg, der_buf, der_len); 274d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_free(der_buf); 275d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(outlen < 0) return -1; 276d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return outlen + 1; 277d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 278d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 279d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* Lookup table to convert tags to character widths, 280d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 0 = UTF8 encoded, -1 is used for non string types 281d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * otherwise it is the number of bytes per character 282d9e397b599b13d642138480a28c14db7a136bf0Adam Langley */ 283d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 284d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic const signed char tag2nbyte[] = { 285d9e397b599b13d642138480a28c14db7a136bf0Adam Langley -1, -1, -1, -1, -1, /* 0-4 */ 286d9e397b599b13d642138480a28c14db7a136bf0Adam Langley -1, -1, -1, -1, -1, /* 5-9 */ 287d9e397b599b13d642138480a28c14db7a136bf0Adam Langley -1, -1, 0, -1, /* 10-13 */ 288d9e397b599b13d642138480a28c14db7a136bf0Adam Langley -1, -1, -1, -1, /* 15-17 */ 289d9e397b599b13d642138480a28c14db7a136bf0Adam Langley -1, 1, 1, /* 18-20 */ 290d9e397b599b13d642138480a28c14db7a136bf0Adam Langley -1, 1, 1, 1, /* 21-24 */ 291d9e397b599b13d642138480a28c14db7a136bf0Adam Langley -1, 1, -1, /* 25-27 */ 292d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 4, -1, 2 /* 28-30 */ 293d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}; 294d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 295d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* This is the main function, print out an 296d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ASN1_STRING taking note of various escape 297d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * and display options. Returns number of 298d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * characters written or -1 if an error 299d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * occurred. 300d9e397b599b13d642138480a28c14db7a136bf0Adam Langley */ 301d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 302d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int do_print_ex(char_io *io_ch, void *arg, unsigned long lflags, ASN1_STRING *str) 303d9e397b599b13d642138480a28c14db7a136bf0Adam Langley{ 304d9e397b599b13d642138480a28c14db7a136bf0Adam Langley int outlen, len; 305d9e397b599b13d642138480a28c14db7a136bf0Adam Langley int type; 306d9e397b599b13d642138480a28c14db7a136bf0Adam Langley char quotes; 307d9e397b599b13d642138480a28c14db7a136bf0Adam Langley unsigned char flags; 308d9e397b599b13d642138480a28c14db7a136bf0Adam Langley quotes = 0; 309d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* Keep a copy of escape flags */ 310d9e397b599b13d642138480a28c14db7a136bf0Adam Langley flags = (unsigned char)(lflags & ESC_FLAGS); 311d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 312d9e397b599b13d642138480a28c14db7a136bf0Adam Langley type = str->type; 313d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 314d9e397b599b13d642138480a28c14db7a136bf0Adam Langley outlen = 0; 315d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 316d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 317d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(lflags & ASN1_STRFLGS_SHOW_TYPE) { 318d9e397b599b13d642138480a28c14db7a136bf0Adam Langley const char *tagname; 319d9e397b599b13d642138480a28c14db7a136bf0Adam Langley tagname = ASN1_tag2str(type); 320d9e397b599b13d642138480a28c14db7a136bf0Adam Langley outlen += strlen(tagname); 321d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(!io_ch(arg, tagname, outlen) || !io_ch(arg, ":", 1)) return -1; 322d9e397b599b13d642138480a28c14db7a136bf0Adam Langley outlen++; 323d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 324d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 325d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* Decide what to do with type, either dump content or display it */ 326d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 327d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* Dump everything */ 328d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(lflags & ASN1_STRFLGS_DUMP_ALL) type = -1; 329d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* Ignore the string type */ 330d9e397b599b13d642138480a28c14db7a136bf0Adam Langley else if(lflags & ASN1_STRFLGS_IGNORE_TYPE) type = 1; 331d9e397b599b13d642138480a28c14db7a136bf0Adam Langley else { 332d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* Else determine width based on type */ 333d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if((type > 0) && (type < 31)) type = tag2nbyte[type]; 334d9e397b599b13d642138480a28c14db7a136bf0Adam Langley else type = -1; 335d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if((type == -1) && !(lflags & ASN1_STRFLGS_DUMP_UNKNOWN)) type = 1; 336d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 337d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 338d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(type == -1) { 339d9e397b599b13d642138480a28c14db7a136bf0Adam Langley len = do_dump(lflags, io_ch, arg, str); 340d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(len < 0) return -1; 341d9e397b599b13d642138480a28c14db7a136bf0Adam Langley outlen += len; 342d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return outlen; 343d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 344d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 345d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(lflags & ASN1_STRFLGS_UTF8_CONVERT) { 346d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* Note: if string is UTF8 and we want 347d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * to convert to UTF8 then we just interpret 348d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * it as 1 byte per character to avoid converting 349d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * twice. 350d9e397b599b13d642138480a28c14db7a136bf0Adam Langley */ 351d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(!type) type = 1; 352d9e397b599b13d642138480a28c14db7a136bf0Adam Langley else type |= BUF_TYPE_CONVUTF8; 353d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 354d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 355d9e397b599b13d642138480a28c14db7a136bf0Adam Langley len = do_buf(str->data, str->length, type, flags, "es, io_ch, NULL); 356d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(len < 0) return -1; 357d9e397b599b13d642138480a28c14db7a136bf0Adam Langley outlen += len; 358d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(quotes) outlen += 2; 359d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(!arg) return outlen; 360d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(quotes && !io_ch(arg, "\"", 1)) return -1; 361d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(do_buf(str->data, str->length, type, flags, NULL, io_ch, arg) < 0) 362d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return -1; 363d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(quotes && !io_ch(arg, "\"", 1)) return -1; 364d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return outlen; 365d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 366d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 367d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* Used for line indenting: print 'indent' spaces */ 368d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 369d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int do_indent(char_io *io_ch, void *arg, int indent) 370d9e397b599b13d642138480a28c14db7a136bf0Adam Langley{ 371d9e397b599b13d642138480a28c14db7a136bf0Adam Langley int i; 372d9e397b599b13d642138480a28c14db7a136bf0Adam Langley for(i = 0; i < indent; i++) 373d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(!io_ch(arg, " ", 1)) return 0; 374d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 1; 375d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 376d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 377d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#define FN_WIDTH_LN 25 378d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#define FN_WIDTH_SN 10 379d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 380d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int do_name_ex(char_io *io_ch, void *arg, X509_NAME *n, 381d9e397b599b13d642138480a28c14db7a136bf0Adam Langley int indent, unsigned long flags) 382d9e397b599b13d642138480a28c14db7a136bf0Adam Langley{ 383d9e397b599b13d642138480a28c14db7a136bf0Adam Langley int i, prev = -1, orflags, cnt; 384d9e397b599b13d642138480a28c14db7a136bf0Adam Langley int fn_opt, fn_nid; 385d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ASN1_OBJECT *fn; 386d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ASN1_STRING *val; 387d9e397b599b13d642138480a28c14db7a136bf0Adam Langley X509_NAME_ENTRY *ent; 388d9e397b599b13d642138480a28c14db7a136bf0Adam Langley char objtmp[80]; 389d9e397b599b13d642138480a28c14db7a136bf0Adam Langley const char *objbuf; 390d9e397b599b13d642138480a28c14db7a136bf0Adam Langley int outlen, len; 391d9e397b599b13d642138480a28c14db7a136bf0Adam Langley const char *sep_dn, *sep_mv, *sep_eq; 392d9e397b599b13d642138480a28c14db7a136bf0Adam Langley int sep_dn_len, sep_mv_len, sep_eq_len; 393d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(indent < 0) indent = 0; 394d9e397b599b13d642138480a28c14db7a136bf0Adam Langley outlen = indent; 395d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(!do_indent(io_ch, arg, indent)) return -1; 396d9e397b599b13d642138480a28c14db7a136bf0Adam Langley switch (flags & XN_FLAG_SEP_MASK) 397d9e397b599b13d642138480a28c14db7a136bf0Adam Langley { 398d9e397b599b13d642138480a28c14db7a136bf0Adam Langley case XN_FLAG_SEP_MULTILINE: 399d9e397b599b13d642138480a28c14db7a136bf0Adam Langley sep_dn = "\n"; 400d9e397b599b13d642138480a28c14db7a136bf0Adam Langley sep_dn_len = 1; 401d9e397b599b13d642138480a28c14db7a136bf0Adam Langley sep_mv = " + "; 402d9e397b599b13d642138480a28c14db7a136bf0Adam Langley sep_mv_len = 3; 403d9e397b599b13d642138480a28c14db7a136bf0Adam Langley break; 404d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 405d9e397b599b13d642138480a28c14db7a136bf0Adam Langley case XN_FLAG_SEP_COMMA_PLUS: 406d9e397b599b13d642138480a28c14db7a136bf0Adam Langley sep_dn = ","; 407d9e397b599b13d642138480a28c14db7a136bf0Adam Langley sep_dn_len = 1; 408d9e397b599b13d642138480a28c14db7a136bf0Adam Langley sep_mv = "+"; 409d9e397b599b13d642138480a28c14db7a136bf0Adam Langley sep_mv_len = 1; 410d9e397b599b13d642138480a28c14db7a136bf0Adam Langley indent = 0; 411d9e397b599b13d642138480a28c14db7a136bf0Adam Langley break; 412d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 413d9e397b599b13d642138480a28c14db7a136bf0Adam Langley case XN_FLAG_SEP_CPLUS_SPC: 414d9e397b599b13d642138480a28c14db7a136bf0Adam Langley sep_dn = ", "; 415d9e397b599b13d642138480a28c14db7a136bf0Adam Langley sep_dn_len = 2; 416d9e397b599b13d642138480a28c14db7a136bf0Adam Langley sep_mv = " + "; 417d9e397b599b13d642138480a28c14db7a136bf0Adam Langley sep_mv_len = 3; 418d9e397b599b13d642138480a28c14db7a136bf0Adam Langley indent = 0; 419d9e397b599b13d642138480a28c14db7a136bf0Adam Langley break; 420d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 421d9e397b599b13d642138480a28c14db7a136bf0Adam Langley case XN_FLAG_SEP_SPLUS_SPC: 422d9e397b599b13d642138480a28c14db7a136bf0Adam Langley sep_dn = "; "; 423d9e397b599b13d642138480a28c14db7a136bf0Adam Langley sep_dn_len = 2; 424d9e397b599b13d642138480a28c14db7a136bf0Adam Langley sep_mv = " + "; 425d9e397b599b13d642138480a28c14db7a136bf0Adam Langley sep_mv_len = 3; 426d9e397b599b13d642138480a28c14db7a136bf0Adam Langley indent = 0; 427d9e397b599b13d642138480a28c14db7a136bf0Adam Langley break; 428d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 429d9e397b599b13d642138480a28c14db7a136bf0Adam Langley default: 430d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return -1; 431d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 432d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 433d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(flags & XN_FLAG_SPC_EQ) { 434d9e397b599b13d642138480a28c14db7a136bf0Adam Langley sep_eq = " = "; 435d9e397b599b13d642138480a28c14db7a136bf0Adam Langley sep_eq_len = 3; 436d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } else { 437d9e397b599b13d642138480a28c14db7a136bf0Adam Langley sep_eq = "="; 438d9e397b599b13d642138480a28c14db7a136bf0Adam Langley sep_eq_len = 1; 439d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 440d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 441d9e397b599b13d642138480a28c14db7a136bf0Adam Langley fn_opt = flags & XN_FLAG_FN_MASK; 442d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 443d9e397b599b13d642138480a28c14db7a136bf0Adam Langley cnt = X509_NAME_entry_count(n); 444d9e397b599b13d642138480a28c14db7a136bf0Adam Langley for(i = 0; i < cnt; i++) { 445d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(flags & XN_FLAG_DN_REV) 446d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ent = X509_NAME_get_entry(n, cnt - i - 1); 447d9e397b599b13d642138480a28c14db7a136bf0Adam Langley else ent = X509_NAME_get_entry(n, i); 448d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(prev != -1) { 449d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(prev == ent->set) { 450d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(!io_ch(arg, sep_mv, sep_mv_len)) return -1; 451d9e397b599b13d642138480a28c14db7a136bf0Adam Langley outlen += sep_mv_len; 452d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } else { 453d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(!io_ch(arg, sep_dn, sep_dn_len)) return -1; 454d9e397b599b13d642138480a28c14db7a136bf0Adam Langley outlen += sep_dn_len; 455d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(!do_indent(io_ch, arg, indent)) return -1; 456d9e397b599b13d642138480a28c14db7a136bf0Adam Langley outlen += indent; 457d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 458d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 459d9e397b599b13d642138480a28c14db7a136bf0Adam Langley prev = ent->set; 460d9e397b599b13d642138480a28c14db7a136bf0Adam Langley fn = X509_NAME_ENTRY_get_object(ent); 461d9e397b599b13d642138480a28c14db7a136bf0Adam Langley val = X509_NAME_ENTRY_get_data(ent); 462d9e397b599b13d642138480a28c14db7a136bf0Adam Langley fn_nid = OBJ_obj2nid(fn); 463d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(fn_opt != XN_FLAG_FN_NONE) { 464d9e397b599b13d642138480a28c14db7a136bf0Adam Langley int objlen, fld_len; 465d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if((fn_opt == XN_FLAG_FN_OID) || (fn_nid==NID_undef) ) { 466d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OBJ_obj2txt(objtmp, sizeof objtmp, fn, 1); 467d9e397b599b13d642138480a28c14db7a136bf0Adam Langley fld_len = 0; /* XXX: what should this be? */ 468d9e397b599b13d642138480a28c14db7a136bf0Adam Langley objbuf = objtmp; 469d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } else { 470d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(fn_opt == XN_FLAG_FN_SN) { 471d9e397b599b13d642138480a28c14db7a136bf0Adam Langley fld_len = FN_WIDTH_SN; 472d9e397b599b13d642138480a28c14db7a136bf0Adam Langley objbuf = OBJ_nid2sn(fn_nid); 473d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } else if(fn_opt == XN_FLAG_FN_LN) { 474d9e397b599b13d642138480a28c14db7a136bf0Adam Langley fld_len = FN_WIDTH_LN; 475d9e397b599b13d642138480a28c14db7a136bf0Adam Langley objbuf = OBJ_nid2ln(fn_nid); 476d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } else { 477d9e397b599b13d642138480a28c14db7a136bf0Adam Langley fld_len = 0; /* XXX: what should this be? */ 478d9e397b599b13d642138480a28c14db7a136bf0Adam Langley objbuf = ""; 479d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 480d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 481d9e397b599b13d642138480a28c14db7a136bf0Adam Langley objlen = strlen(objbuf); 482d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(!io_ch(arg, objbuf, objlen)) return -1; 483d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if ((objlen < fld_len) && (flags & XN_FLAG_FN_ALIGN)) { 484d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!do_indent(io_ch, arg, fld_len - objlen)) return -1; 485d9e397b599b13d642138480a28c14db7a136bf0Adam Langley outlen += fld_len - objlen; 486d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 487d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(!io_ch(arg, sep_eq, sep_eq_len)) return -1; 488d9e397b599b13d642138480a28c14db7a136bf0Adam Langley outlen += objlen + sep_eq_len; 489d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 490d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* If the field name is unknown then fix up the DER dump 491d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * flag. We might want to limit this further so it will 492d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * DER dump on anything other than a few 'standard' fields. 493d9e397b599b13d642138480a28c14db7a136bf0Adam Langley */ 494d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if((fn_nid == NID_undef) && (flags & XN_FLAG_DUMP_UNKNOWN_FIELDS)) 495d9e397b599b13d642138480a28c14db7a136bf0Adam Langley orflags = ASN1_STRFLGS_DUMP_ALL; 496d9e397b599b13d642138480a28c14db7a136bf0Adam Langley else orflags = 0; 497d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 498d9e397b599b13d642138480a28c14db7a136bf0Adam Langley len = do_print_ex(io_ch, arg, flags | orflags, val); 499d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(len < 0) return -1; 500d9e397b599b13d642138480a28c14db7a136bf0Adam Langley outlen += len; 501d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 502d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return outlen; 503d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 504d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 505d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* Wrappers round the main functions */ 506d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 507d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint X509_NAME_print_ex(BIO *out, X509_NAME *nm, int indent, unsigned long flags) 508d9e397b599b13d642138480a28c14db7a136bf0Adam Langley{ 509d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(flags == XN_FLAG_COMPAT) 510d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return X509_NAME_print(out, nm, indent); 511d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return do_name_ex(send_bio_chars, out, nm, indent, flags); 512d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 513d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 514d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#ifndef OPENSSL_NO_FP_API 515d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent, unsigned long flags) 516d9e397b599b13d642138480a28c14db7a136bf0Adam Langley{ 517d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(flags == XN_FLAG_COMPAT) 518d9e397b599b13d642138480a28c14db7a136bf0Adam Langley { 519d9e397b599b13d642138480a28c14db7a136bf0Adam Langley BIO *btmp; 520d9e397b599b13d642138480a28c14db7a136bf0Adam Langley int ret; 521d9e397b599b13d642138480a28c14db7a136bf0Adam Langley btmp = BIO_new_fp(fp, BIO_NOCLOSE); 522d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(!btmp) return -1; 523d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ret = X509_NAME_print(btmp, nm, indent); 524d9e397b599b13d642138480a28c14db7a136bf0Adam Langley BIO_free(btmp); 525d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return ret; 526d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 527d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return do_name_ex(send_fp_chars, fp, nm, indent, flags); 528d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 529d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#endif 530d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 531d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags) 532d9e397b599b13d642138480a28c14db7a136bf0Adam Langley{ 533d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return do_print_ex(send_bio_chars, out, flags, str); 534d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 535d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 536d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#ifndef OPENSSL_NO_FP_API 537d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags) 538d9e397b599b13d642138480a28c14db7a136bf0Adam Langley{ 539d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return do_print_ex(send_fp_chars, fp, flags, str); 540d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 541d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#endif 542d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 543d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* Utility function: convert any string type to UTF8, returns number of bytes 544d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * in output string or a negative error code 545d9e397b599b13d642138480a28c14db7a136bf0Adam Langley */ 546d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 547d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in) 548d9e397b599b13d642138480a28c14db7a136bf0Adam Langley{ 549d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ASN1_STRING stmp, *str = &stmp; 550d9e397b599b13d642138480a28c14db7a136bf0Adam Langley int mbflag, type, ret; 551d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(!in) return -1; 552d9e397b599b13d642138480a28c14db7a136bf0Adam Langley type = in->type; 553d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if((type < 0) || (type > 30)) return -1; 554d9e397b599b13d642138480a28c14db7a136bf0Adam Langley mbflag = tag2nbyte[type]; 555d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(mbflag == -1) return -1; 556d9e397b599b13d642138480a28c14db7a136bf0Adam Langley mbflag |= MBSTRING_FLAG; 557d9e397b599b13d642138480a28c14db7a136bf0Adam Langley stmp.data = NULL; 558d9e397b599b13d642138480a28c14db7a136bf0Adam Langley stmp.length = 0; 559d9e397b599b13d642138480a28c14db7a136bf0Adam Langley stmp.flags = 0; 560d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ret = ASN1_mbstring_copy(&str, in->data, in->length, mbflag, B_ASN1_UTF8STRING); 561d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(ret < 0) return ret; 562d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *out = stmp.data; 563d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return stmp.length; 564d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 565