1*0Sstevel@tonic-gate /* apps/apps.c */ 2*0Sstevel@tonic-gate /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3*0Sstevel@tonic-gate * All rights reserved. 4*0Sstevel@tonic-gate * 5*0Sstevel@tonic-gate * This package is an SSL implementation written 6*0Sstevel@tonic-gate * by Eric Young (eay@cryptsoft.com). 7*0Sstevel@tonic-gate * The implementation was written so as to conform with Netscapes SSL. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * This library is free for commercial and non-commercial use as long as 10*0Sstevel@tonic-gate * the following conditions are aheared to. The following conditions 11*0Sstevel@tonic-gate * apply to all code found in this distribution, be it the RC4, RSA, 12*0Sstevel@tonic-gate * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13*0Sstevel@tonic-gate * included with this distribution is covered by the same copyright terms 14*0Sstevel@tonic-gate * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15*0Sstevel@tonic-gate * 16*0Sstevel@tonic-gate * Copyright remains Eric Young's, and as such any Copyright notices in 17*0Sstevel@tonic-gate * the code are not to be removed. 18*0Sstevel@tonic-gate * If this package is used in a product, Eric Young should be given attribution 19*0Sstevel@tonic-gate * as the author of the parts of the library used. 20*0Sstevel@tonic-gate * This can be in the form of a textual message at program startup or 21*0Sstevel@tonic-gate * in documentation (online or textual) provided with the package. 22*0Sstevel@tonic-gate * 23*0Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without 24*0Sstevel@tonic-gate * modification, are permitted provided that the following conditions 25*0Sstevel@tonic-gate * are met: 26*0Sstevel@tonic-gate * 1. Redistributions of source code must retain the copyright 27*0Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer. 28*0Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright 29*0Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in the 30*0Sstevel@tonic-gate * documentation and/or other materials provided with the distribution. 31*0Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this software 32*0Sstevel@tonic-gate * must display the following acknowledgement: 33*0Sstevel@tonic-gate * "This product includes cryptographic software written by 34*0Sstevel@tonic-gate * Eric Young (eay@cryptsoft.com)" 35*0Sstevel@tonic-gate * The word 'cryptographic' can be left out if the rouines from the library 36*0Sstevel@tonic-gate * being used are not cryptographic related :-). 37*0Sstevel@tonic-gate * 4. If you include any Windows specific code (or a derivative thereof) from 38*0Sstevel@tonic-gate * the apps directory (application code) you must include an acknowledgement: 39*0Sstevel@tonic-gate * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40*0Sstevel@tonic-gate * 41*0Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42*0Sstevel@tonic-gate * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43*0Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44*0Sstevel@tonic-gate * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45*0Sstevel@tonic-gate * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46*0Sstevel@tonic-gate * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47*0Sstevel@tonic-gate * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48*0Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49*0Sstevel@tonic-gate * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50*0Sstevel@tonic-gate * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51*0Sstevel@tonic-gate * SUCH DAMAGE. 52*0Sstevel@tonic-gate * 53*0Sstevel@tonic-gate * The licence and distribution terms for any publically available version or 54*0Sstevel@tonic-gate * derivative of this code cannot be changed. i.e. this code cannot simply be 55*0Sstevel@tonic-gate * copied and put under another distribution licence 56*0Sstevel@tonic-gate * [including the GNU Public Licence.] 57*0Sstevel@tonic-gate */ 58*0Sstevel@tonic-gate /* ==================================================================== 59*0Sstevel@tonic-gate * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. 60*0Sstevel@tonic-gate * 61*0Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without 62*0Sstevel@tonic-gate * modification, are permitted provided that the following conditions 63*0Sstevel@tonic-gate * are met: 64*0Sstevel@tonic-gate * 65*0Sstevel@tonic-gate * 1. Redistributions of source code must retain the above copyright 66*0Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer. 67*0Sstevel@tonic-gate * 68*0Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright 69*0Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in 70*0Sstevel@tonic-gate * the documentation and/or other materials provided with the 71*0Sstevel@tonic-gate * distribution. 72*0Sstevel@tonic-gate * 73*0Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this 74*0Sstevel@tonic-gate * software must display the following acknowledgment: 75*0Sstevel@tonic-gate * "This product includes software developed by the OpenSSL Project 76*0Sstevel@tonic-gate * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 77*0Sstevel@tonic-gate * 78*0Sstevel@tonic-gate * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 79*0Sstevel@tonic-gate * endorse or promote products derived from this software without 80*0Sstevel@tonic-gate * prior written permission. For written permission, please contact 81*0Sstevel@tonic-gate * openssl-core@openssl.org. 82*0Sstevel@tonic-gate * 83*0Sstevel@tonic-gate * 5. Products derived from this software may not be called "OpenSSL" 84*0Sstevel@tonic-gate * nor may "OpenSSL" appear in their names without prior written 85*0Sstevel@tonic-gate * permission of the OpenSSL Project. 86*0Sstevel@tonic-gate * 87*0Sstevel@tonic-gate * 6. Redistributions of any form whatsoever must retain the following 88*0Sstevel@tonic-gate * acknowledgment: 89*0Sstevel@tonic-gate * "This product includes software developed by the OpenSSL Project 90*0Sstevel@tonic-gate * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 91*0Sstevel@tonic-gate * 92*0Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 93*0Sstevel@tonic-gate * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 94*0Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 95*0Sstevel@tonic-gate * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 96*0Sstevel@tonic-gate * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 97*0Sstevel@tonic-gate * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 98*0Sstevel@tonic-gate * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 99*0Sstevel@tonic-gate * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 100*0Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 101*0Sstevel@tonic-gate * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 102*0Sstevel@tonic-gate * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 103*0Sstevel@tonic-gate * OF THE POSSIBILITY OF SUCH DAMAGE. 104*0Sstevel@tonic-gate * ==================================================================== 105*0Sstevel@tonic-gate * 106*0Sstevel@tonic-gate * This product includes cryptographic software written by Eric Young 107*0Sstevel@tonic-gate * (eay@cryptsoft.com). This product includes software written by Tim 108*0Sstevel@tonic-gate * Hudson (tjh@cryptsoft.com). 109*0Sstevel@tonic-gate * 110*0Sstevel@tonic-gate */ 111*0Sstevel@tonic-gate 112*0Sstevel@tonic-gate #include <stdio.h> 113*0Sstevel@tonic-gate #include <stdlib.h> 114*0Sstevel@tonic-gate #include <string.h> 115*0Sstevel@tonic-gate #include <sys/types.h> 116*0Sstevel@tonic-gate #include <sys/stat.h> 117*0Sstevel@tonic-gate #include <ctype.h> 118*0Sstevel@tonic-gate #include <openssl/err.h> 119*0Sstevel@tonic-gate #include <openssl/x509.h> 120*0Sstevel@tonic-gate #include <openssl/x509v3.h> 121*0Sstevel@tonic-gate #include <openssl/pem.h> 122*0Sstevel@tonic-gate #include <openssl/pkcs12.h> 123*0Sstevel@tonic-gate #include <openssl/ui.h> 124*0Sstevel@tonic-gate #include <openssl/safestack.h> 125*0Sstevel@tonic-gate #ifndef OPENSSL_NO_ENGINE 126*0Sstevel@tonic-gate #include <openssl/engine.h> 127*0Sstevel@tonic-gate #endif 128*0Sstevel@tonic-gate 129*0Sstevel@tonic-gate #ifdef OPENSSL_SYS_WINDOWS 130*0Sstevel@tonic-gate #define strcasecmp _stricmp 131*0Sstevel@tonic-gate #else 132*0Sstevel@tonic-gate # ifdef NO_STRINGS_H 133*0Sstevel@tonic-gate int strcasecmp(); 134*0Sstevel@tonic-gate # else 135*0Sstevel@tonic-gate # include <strings.h> 136*0Sstevel@tonic-gate # endif /* NO_STRINGS_H */ 137*0Sstevel@tonic-gate #endif 138*0Sstevel@tonic-gate 139*0Sstevel@tonic-gate #define NON_MAIN 140*0Sstevel@tonic-gate #include "apps.h" 141*0Sstevel@tonic-gate #undef NON_MAIN 142*0Sstevel@tonic-gate 143*0Sstevel@tonic-gate typedef struct { 144*0Sstevel@tonic-gate char *name; 145*0Sstevel@tonic-gate unsigned long flag; 146*0Sstevel@tonic-gate unsigned long mask; 147*0Sstevel@tonic-gate } NAME_EX_TBL; 148*0Sstevel@tonic-gate 149*0Sstevel@tonic-gate static UI_METHOD *ui_method = NULL; 150*0Sstevel@tonic-gate 151*0Sstevel@tonic-gate static int set_table_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl); 152*0Sstevel@tonic-gate static int set_multi_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl); 153*0Sstevel@tonic-gate 154*0Sstevel@tonic-gate #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA) 155*0Sstevel@tonic-gate /* Looks like this stuff is worth moving into separate function */ 156*0Sstevel@tonic-gate static EVP_PKEY * 157*0Sstevel@tonic-gate load_netscape_key(BIO *err, BIO *key, const char *file, 158*0Sstevel@tonic-gate const char *key_descrip, int format); 159*0Sstevel@tonic-gate #endif 160*0Sstevel@tonic-gate 161*0Sstevel@tonic-gate int app_init(long mesgwin); 162*0Sstevel@tonic-gate #ifdef undef /* never finished - probably never will be :-) */ 163*0Sstevel@tonic-gate int args_from_file(char *file, int *argc, char **argv[]) 164*0Sstevel@tonic-gate { 165*0Sstevel@tonic-gate FILE *fp; 166*0Sstevel@tonic-gate int num,i; 167*0Sstevel@tonic-gate unsigned int len; 168*0Sstevel@tonic-gate static char *buf=NULL; 169*0Sstevel@tonic-gate static char **arg=NULL; 170*0Sstevel@tonic-gate char *p; 171*0Sstevel@tonic-gate struct stat stbuf; 172*0Sstevel@tonic-gate 173*0Sstevel@tonic-gate if (stat(file,&stbuf) < 0) return(0); 174*0Sstevel@tonic-gate 175*0Sstevel@tonic-gate fp=fopen(file,"r"); 176*0Sstevel@tonic-gate if (fp == NULL) 177*0Sstevel@tonic-gate return(0); 178*0Sstevel@tonic-gate 179*0Sstevel@tonic-gate *argc=0; 180*0Sstevel@tonic-gate *argv=NULL; 181*0Sstevel@tonic-gate 182*0Sstevel@tonic-gate len=(unsigned int)stbuf.st_size; 183*0Sstevel@tonic-gate if (buf != NULL) OPENSSL_free(buf); 184*0Sstevel@tonic-gate buf=(char *)OPENSSL_malloc(len+1); 185*0Sstevel@tonic-gate if (buf == NULL) return(0); 186*0Sstevel@tonic-gate 187*0Sstevel@tonic-gate len=fread(buf,1,len,fp); 188*0Sstevel@tonic-gate if (len <= 1) return(0); 189*0Sstevel@tonic-gate buf[len]='\0'; 190*0Sstevel@tonic-gate 191*0Sstevel@tonic-gate i=0; 192*0Sstevel@tonic-gate for (p=buf; *p; p++) 193*0Sstevel@tonic-gate if (*p == '\n') i++; 194*0Sstevel@tonic-gate if (arg != NULL) OPENSSL_free(arg); 195*0Sstevel@tonic-gate arg=(char **)OPENSSL_malloc(sizeof(char *)*(i*2)); 196*0Sstevel@tonic-gate 197*0Sstevel@tonic-gate *argv=arg; 198*0Sstevel@tonic-gate num=0; 199*0Sstevel@tonic-gate p=buf; 200*0Sstevel@tonic-gate for (;;) 201*0Sstevel@tonic-gate { 202*0Sstevel@tonic-gate if (!*p) break; 203*0Sstevel@tonic-gate if (*p == '#') /* comment line */ 204*0Sstevel@tonic-gate { 205*0Sstevel@tonic-gate while (*p && (*p != '\n')) p++; 206*0Sstevel@tonic-gate continue; 207*0Sstevel@tonic-gate } 208*0Sstevel@tonic-gate /* else we have a line */ 209*0Sstevel@tonic-gate *(arg++)=p; 210*0Sstevel@tonic-gate num++; 211*0Sstevel@tonic-gate while (*p && ((*p != ' ') && (*p != '\t') && (*p != '\n'))) 212*0Sstevel@tonic-gate p++; 213*0Sstevel@tonic-gate if (!*p) break; 214*0Sstevel@tonic-gate if (*p == '\n') 215*0Sstevel@tonic-gate { 216*0Sstevel@tonic-gate *(p++)='\0'; 217*0Sstevel@tonic-gate continue; 218*0Sstevel@tonic-gate } 219*0Sstevel@tonic-gate /* else it is a tab or space */ 220*0Sstevel@tonic-gate p++; 221*0Sstevel@tonic-gate while (*p && ((*p == ' ') || (*p == '\t') || (*p == '\n'))) 222*0Sstevel@tonic-gate p++; 223*0Sstevel@tonic-gate if (!*p) break; 224*0Sstevel@tonic-gate if (*p == '\n') 225*0Sstevel@tonic-gate { 226*0Sstevel@tonic-gate p++; 227*0Sstevel@tonic-gate continue; 228*0Sstevel@tonic-gate } 229*0Sstevel@tonic-gate *(arg++)=p++; 230*0Sstevel@tonic-gate num++; 231*0Sstevel@tonic-gate while (*p && (*p != '\n')) p++; 232*0Sstevel@tonic-gate if (!*p) break; 233*0Sstevel@tonic-gate /* else *p == '\n' */ 234*0Sstevel@tonic-gate *(p++)='\0'; 235*0Sstevel@tonic-gate } 236*0Sstevel@tonic-gate *argc=num; 237*0Sstevel@tonic-gate return(1); 238*0Sstevel@tonic-gate } 239*0Sstevel@tonic-gate #endif 240*0Sstevel@tonic-gate 241*0Sstevel@tonic-gate int str2fmt(char *s) 242*0Sstevel@tonic-gate { 243*0Sstevel@tonic-gate if ((*s == 'D') || (*s == 'd')) 244*0Sstevel@tonic-gate return(FORMAT_ASN1); 245*0Sstevel@tonic-gate else if ((*s == 'T') || (*s == 't')) 246*0Sstevel@tonic-gate return(FORMAT_TEXT); 247*0Sstevel@tonic-gate else if ((*s == 'P') || (*s == 'p')) 248*0Sstevel@tonic-gate return(FORMAT_PEM); 249*0Sstevel@tonic-gate else if ((*s == 'N') || (*s == 'n')) 250*0Sstevel@tonic-gate return(FORMAT_NETSCAPE); 251*0Sstevel@tonic-gate else if ((*s == 'S') || (*s == 's')) 252*0Sstevel@tonic-gate return(FORMAT_SMIME); 253*0Sstevel@tonic-gate else if ((*s == '1') 254*0Sstevel@tonic-gate || (strcmp(s,"PKCS12") == 0) || (strcmp(s,"pkcs12") == 0) 255*0Sstevel@tonic-gate || (strcmp(s,"P12") == 0) || (strcmp(s,"p12") == 0)) 256*0Sstevel@tonic-gate return(FORMAT_PKCS12); 257*0Sstevel@tonic-gate else if ((*s == 'E') || (*s == 'e')) 258*0Sstevel@tonic-gate return(FORMAT_ENGINE); 259*0Sstevel@tonic-gate else 260*0Sstevel@tonic-gate return(FORMAT_UNDEF); 261*0Sstevel@tonic-gate } 262*0Sstevel@tonic-gate 263*0Sstevel@tonic-gate #if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16) 264*0Sstevel@tonic-gate void program_name(char *in, char *out, int size) 265*0Sstevel@tonic-gate { 266*0Sstevel@tonic-gate int i,n; 267*0Sstevel@tonic-gate char *p=NULL; 268*0Sstevel@tonic-gate 269*0Sstevel@tonic-gate n=strlen(in); 270*0Sstevel@tonic-gate /* find the last '/', '\' or ':' */ 271*0Sstevel@tonic-gate for (i=n-1; i>0; i--) 272*0Sstevel@tonic-gate { 273*0Sstevel@tonic-gate if ((in[i] == '/') || (in[i] == '\\') || (in[i] == ':')) 274*0Sstevel@tonic-gate { 275*0Sstevel@tonic-gate p= &(in[i+1]); 276*0Sstevel@tonic-gate break; 277*0Sstevel@tonic-gate } 278*0Sstevel@tonic-gate } 279*0Sstevel@tonic-gate if (p == NULL) 280*0Sstevel@tonic-gate p=in; 281*0Sstevel@tonic-gate n=strlen(p); 282*0Sstevel@tonic-gate /* strip off trailing .exe if present. */ 283*0Sstevel@tonic-gate if ((n > 4) && (p[n-4] == '.') && 284*0Sstevel@tonic-gate ((p[n-3] == 'e') || (p[n-3] == 'E')) && 285*0Sstevel@tonic-gate ((p[n-2] == 'x') || (p[n-2] == 'X')) && 286*0Sstevel@tonic-gate ((p[n-1] == 'e') || (p[n-1] == 'E'))) 287*0Sstevel@tonic-gate n-=4; 288*0Sstevel@tonic-gate if (n > size-1) 289*0Sstevel@tonic-gate n=size-1; 290*0Sstevel@tonic-gate 291*0Sstevel@tonic-gate for (i=0; i<n; i++) 292*0Sstevel@tonic-gate { 293*0Sstevel@tonic-gate if ((p[i] >= 'A') && (p[i] <= 'Z')) 294*0Sstevel@tonic-gate out[i]=p[i]-'A'+'a'; 295*0Sstevel@tonic-gate else 296*0Sstevel@tonic-gate out[i]=p[i]; 297*0Sstevel@tonic-gate } 298*0Sstevel@tonic-gate out[n]='\0'; 299*0Sstevel@tonic-gate } 300*0Sstevel@tonic-gate #else 301*0Sstevel@tonic-gate #ifdef OPENSSL_SYS_VMS 302*0Sstevel@tonic-gate void program_name(char *in, char *out, int size) 303*0Sstevel@tonic-gate { 304*0Sstevel@tonic-gate char *p=in, *q; 305*0Sstevel@tonic-gate char *chars=":]>"; 306*0Sstevel@tonic-gate 307*0Sstevel@tonic-gate while(*chars != '\0') 308*0Sstevel@tonic-gate { 309*0Sstevel@tonic-gate q=strrchr(p,*chars); 310*0Sstevel@tonic-gate if (q > p) 311*0Sstevel@tonic-gate p = q + 1; 312*0Sstevel@tonic-gate chars++; 313*0Sstevel@tonic-gate } 314*0Sstevel@tonic-gate 315*0Sstevel@tonic-gate q=strrchr(p,'.'); 316*0Sstevel@tonic-gate if (q == NULL) 317*0Sstevel@tonic-gate q = p + strlen(p); 318*0Sstevel@tonic-gate strncpy(out,p,size-1); 319*0Sstevel@tonic-gate if (q-p >= size) 320*0Sstevel@tonic-gate { 321*0Sstevel@tonic-gate out[size-1]='\0'; 322*0Sstevel@tonic-gate } 323*0Sstevel@tonic-gate else 324*0Sstevel@tonic-gate { 325*0Sstevel@tonic-gate out[q-p]='\0'; 326*0Sstevel@tonic-gate } 327*0Sstevel@tonic-gate } 328*0Sstevel@tonic-gate #else 329*0Sstevel@tonic-gate void program_name(char *in, char *out, int size) 330*0Sstevel@tonic-gate { 331*0Sstevel@tonic-gate char *p; 332*0Sstevel@tonic-gate 333*0Sstevel@tonic-gate p=strrchr(in,'/'); 334*0Sstevel@tonic-gate if (p != NULL) 335*0Sstevel@tonic-gate p++; 336*0Sstevel@tonic-gate else 337*0Sstevel@tonic-gate p=in; 338*0Sstevel@tonic-gate BUF_strlcpy(out,p,size); 339*0Sstevel@tonic-gate } 340*0Sstevel@tonic-gate #endif 341*0Sstevel@tonic-gate #endif 342*0Sstevel@tonic-gate 343*0Sstevel@tonic-gate #ifdef OPENSSL_SYS_WIN32 344*0Sstevel@tonic-gate int WIN32_rename(char *from, char *to) 345*0Sstevel@tonic-gate { 346*0Sstevel@tonic-gate #ifndef OPENSSL_SYS_WINCE 347*0Sstevel@tonic-gate /* Windows rename gives an error if 'to' exists, so delete it 348*0Sstevel@tonic-gate * first and ignore file not found errror 349*0Sstevel@tonic-gate */ 350*0Sstevel@tonic-gate if((remove(to) != 0) && (errno != ENOENT)) 351*0Sstevel@tonic-gate return -1; 352*0Sstevel@tonic-gate #undef rename 353*0Sstevel@tonic-gate return rename(from, to); 354*0Sstevel@tonic-gate #else 355*0Sstevel@tonic-gate /* convert strings to UNICODE */ 356*0Sstevel@tonic-gate { 357*0Sstevel@tonic-gate BOOL result = FALSE; 358*0Sstevel@tonic-gate WCHAR* wfrom; 359*0Sstevel@tonic-gate WCHAR* wto; 360*0Sstevel@tonic-gate int i; 361*0Sstevel@tonic-gate wfrom = malloc((strlen(from)+1)*2); 362*0Sstevel@tonic-gate wto = malloc((strlen(to)+1)*2); 363*0Sstevel@tonic-gate if (wfrom != NULL && wto != NULL) 364*0Sstevel@tonic-gate { 365*0Sstevel@tonic-gate for (i=0; i<(int)strlen(from)+1; i++) 366*0Sstevel@tonic-gate wfrom[i] = (short)from[i]; 367*0Sstevel@tonic-gate for (i=0; i<(int)strlen(to)+1; i++) 368*0Sstevel@tonic-gate wto[i] = (short)to[i]; 369*0Sstevel@tonic-gate result = MoveFile(wfrom, wto); 370*0Sstevel@tonic-gate } 371*0Sstevel@tonic-gate if (wfrom != NULL) 372*0Sstevel@tonic-gate free(wfrom); 373*0Sstevel@tonic-gate if (wto != NULL) 374*0Sstevel@tonic-gate free(wto); 375*0Sstevel@tonic-gate return result; 376*0Sstevel@tonic-gate } 377*0Sstevel@tonic-gate #endif 378*0Sstevel@tonic-gate } 379*0Sstevel@tonic-gate #endif 380*0Sstevel@tonic-gate 381*0Sstevel@tonic-gate #ifdef OPENSSL_SYS_VMS 382*0Sstevel@tonic-gate int VMS_strcasecmp(const char *str1, const char *str2) 383*0Sstevel@tonic-gate { 384*0Sstevel@tonic-gate while (*str1 && *str2) 385*0Sstevel@tonic-gate { 386*0Sstevel@tonic-gate int res = toupper(*str1) - toupper(*str2); 387*0Sstevel@tonic-gate if (res) return res < 0 ? -1 : 1; 388*0Sstevel@tonic-gate } 389*0Sstevel@tonic-gate if (*str1) 390*0Sstevel@tonic-gate return 1; 391*0Sstevel@tonic-gate if (*str2) 392*0Sstevel@tonic-gate return -1; 393*0Sstevel@tonic-gate return 0; 394*0Sstevel@tonic-gate } 395*0Sstevel@tonic-gate #endif 396*0Sstevel@tonic-gate 397*0Sstevel@tonic-gate int chopup_args(ARGS *arg, char *buf, int *argc, char **argv[]) 398*0Sstevel@tonic-gate { 399*0Sstevel@tonic-gate int num,len,i; 400*0Sstevel@tonic-gate char *p; 401*0Sstevel@tonic-gate 402*0Sstevel@tonic-gate *argc=0; 403*0Sstevel@tonic-gate *argv=NULL; 404*0Sstevel@tonic-gate 405*0Sstevel@tonic-gate len=strlen(buf); 406*0Sstevel@tonic-gate i=0; 407*0Sstevel@tonic-gate if (arg->count == 0) 408*0Sstevel@tonic-gate { 409*0Sstevel@tonic-gate arg->count=20; 410*0Sstevel@tonic-gate arg->data=(char **)OPENSSL_malloc(sizeof(char *)*arg->count); 411*0Sstevel@tonic-gate } 412*0Sstevel@tonic-gate for (i=0; i<arg->count; i++) 413*0Sstevel@tonic-gate arg->data[i]=NULL; 414*0Sstevel@tonic-gate 415*0Sstevel@tonic-gate num=0; 416*0Sstevel@tonic-gate p=buf; 417*0Sstevel@tonic-gate for (;;) 418*0Sstevel@tonic-gate { 419*0Sstevel@tonic-gate /* first scan over white space */ 420*0Sstevel@tonic-gate if (!*p) break; 421*0Sstevel@tonic-gate while (*p && ((*p == ' ') || (*p == '\t') || (*p == '\n'))) 422*0Sstevel@tonic-gate p++; 423*0Sstevel@tonic-gate if (!*p) break; 424*0Sstevel@tonic-gate 425*0Sstevel@tonic-gate /* The start of something good :-) */ 426*0Sstevel@tonic-gate if (num >= arg->count) 427*0Sstevel@tonic-gate { 428*0Sstevel@tonic-gate arg->count+=20; 429*0Sstevel@tonic-gate arg->data=(char **)OPENSSL_realloc(arg->data, 430*0Sstevel@tonic-gate sizeof(char *)*arg->count); 431*0Sstevel@tonic-gate if (argc == 0) return(0); 432*0Sstevel@tonic-gate } 433*0Sstevel@tonic-gate arg->data[num++]=p; 434*0Sstevel@tonic-gate 435*0Sstevel@tonic-gate /* now look for the end of this */ 436*0Sstevel@tonic-gate if ((*p == '\'') || (*p == '\"')) /* scan for closing quote */ 437*0Sstevel@tonic-gate { 438*0Sstevel@tonic-gate i= *(p++); 439*0Sstevel@tonic-gate arg->data[num-1]++; /* jump over quote */ 440*0Sstevel@tonic-gate while (*p && (*p != i)) 441*0Sstevel@tonic-gate p++; 442*0Sstevel@tonic-gate *p='\0'; 443*0Sstevel@tonic-gate } 444*0Sstevel@tonic-gate else 445*0Sstevel@tonic-gate { 446*0Sstevel@tonic-gate while (*p && ((*p != ' ') && 447*0Sstevel@tonic-gate (*p != '\t') && (*p != '\n'))) 448*0Sstevel@tonic-gate p++; 449*0Sstevel@tonic-gate 450*0Sstevel@tonic-gate if (*p == '\0') 451*0Sstevel@tonic-gate p--; 452*0Sstevel@tonic-gate else 453*0Sstevel@tonic-gate *p='\0'; 454*0Sstevel@tonic-gate } 455*0Sstevel@tonic-gate p++; 456*0Sstevel@tonic-gate } 457*0Sstevel@tonic-gate *argc=num; 458*0Sstevel@tonic-gate *argv=arg->data; 459*0Sstevel@tonic-gate return(1); 460*0Sstevel@tonic-gate } 461*0Sstevel@tonic-gate 462*0Sstevel@tonic-gate #ifndef APP_INIT 463*0Sstevel@tonic-gate int app_init(long mesgwin) 464*0Sstevel@tonic-gate { 465*0Sstevel@tonic-gate return(1); 466*0Sstevel@tonic-gate } 467*0Sstevel@tonic-gate #endif 468*0Sstevel@tonic-gate 469*0Sstevel@tonic-gate 470*0Sstevel@tonic-gate int dump_cert_text (BIO *out, X509 *x) 471*0Sstevel@tonic-gate { 472*0Sstevel@tonic-gate char *p; 473*0Sstevel@tonic-gate 474*0Sstevel@tonic-gate p=X509_NAME_oneline(X509_get_subject_name(x),NULL,0); 475*0Sstevel@tonic-gate BIO_puts(out,"subject="); 476*0Sstevel@tonic-gate BIO_puts(out,p); 477*0Sstevel@tonic-gate OPENSSL_free(p); 478*0Sstevel@tonic-gate 479*0Sstevel@tonic-gate p=X509_NAME_oneline(X509_get_issuer_name(x),NULL,0); 480*0Sstevel@tonic-gate BIO_puts(out,"\nissuer="); 481*0Sstevel@tonic-gate BIO_puts(out,p); 482*0Sstevel@tonic-gate BIO_puts(out,"\n"); 483*0Sstevel@tonic-gate OPENSSL_free(p); 484*0Sstevel@tonic-gate 485*0Sstevel@tonic-gate return 0; 486*0Sstevel@tonic-gate } 487*0Sstevel@tonic-gate 488*0Sstevel@tonic-gate static int ui_open(UI *ui) 489*0Sstevel@tonic-gate { 490*0Sstevel@tonic-gate return UI_method_get_opener(UI_OpenSSL())(ui); 491*0Sstevel@tonic-gate } 492*0Sstevel@tonic-gate static int ui_read(UI *ui, UI_STRING *uis) 493*0Sstevel@tonic-gate { 494*0Sstevel@tonic-gate if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD 495*0Sstevel@tonic-gate && UI_get0_user_data(ui)) 496*0Sstevel@tonic-gate { 497*0Sstevel@tonic-gate switch(UI_get_string_type(uis)) 498*0Sstevel@tonic-gate { 499*0Sstevel@tonic-gate case UIT_PROMPT: 500*0Sstevel@tonic-gate case UIT_VERIFY: 501*0Sstevel@tonic-gate { 502*0Sstevel@tonic-gate const char *password = 503*0Sstevel@tonic-gate ((PW_CB_DATA *)UI_get0_user_data(ui))->password; 504*0Sstevel@tonic-gate if (password && password[0] != '\0') 505*0Sstevel@tonic-gate { 506*0Sstevel@tonic-gate UI_set_result(ui, uis, password); 507*0Sstevel@tonic-gate return 1; 508*0Sstevel@tonic-gate } 509*0Sstevel@tonic-gate } 510*0Sstevel@tonic-gate default: 511*0Sstevel@tonic-gate break; 512*0Sstevel@tonic-gate } 513*0Sstevel@tonic-gate } 514*0Sstevel@tonic-gate return UI_method_get_reader(UI_OpenSSL())(ui, uis); 515*0Sstevel@tonic-gate } 516*0Sstevel@tonic-gate static int ui_write(UI *ui, UI_STRING *uis) 517*0Sstevel@tonic-gate { 518*0Sstevel@tonic-gate if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD 519*0Sstevel@tonic-gate && UI_get0_user_data(ui)) 520*0Sstevel@tonic-gate { 521*0Sstevel@tonic-gate switch(UI_get_string_type(uis)) 522*0Sstevel@tonic-gate { 523*0Sstevel@tonic-gate case UIT_PROMPT: 524*0Sstevel@tonic-gate case UIT_VERIFY: 525*0Sstevel@tonic-gate { 526*0Sstevel@tonic-gate const char *password = 527*0Sstevel@tonic-gate ((PW_CB_DATA *)UI_get0_user_data(ui))->password; 528*0Sstevel@tonic-gate if (password && password[0] != '\0') 529*0Sstevel@tonic-gate return 1; 530*0Sstevel@tonic-gate } 531*0Sstevel@tonic-gate default: 532*0Sstevel@tonic-gate break; 533*0Sstevel@tonic-gate } 534*0Sstevel@tonic-gate } 535*0Sstevel@tonic-gate return UI_method_get_writer(UI_OpenSSL())(ui, uis); 536*0Sstevel@tonic-gate } 537*0Sstevel@tonic-gate static int ui_close(UI *ui) 538*0Sstevel@tonic-gate { 539*0Sstevel@tonic-gate return UI_method_get_closer(UI_OpenSSL())(ui); 540*0Sstevel@tonic-gate } 541*0Sstevel@tonic-gate int setup_ui_method(void) 542*0Sstevel@tonic-gate { 543*0Sstevel@tonic-gate ui_method = UI_create_method("OpenSSL application user interface"); 544*0Sstevel@tonic-gate UI_method_set_opener(ui_method, ui_open); 545*0Sstevel@tonic-gate UI_method_set_reader(ui_method, ui_read); 546*0Sstevel@tonic-gate UI_method_set_writer(ui_method, ui_write); 547*0Sstevel@tonic-gate UI_method_set_closer(ui_method, ui_close); 548*0Sstevel@tonic-gate return 0; 549*0Sstevel@tonic-gate } 550*0Sstevel@tonic-gate void destroy_ui_method(void) 551*0Sstevel@tonic-gate { 552*0Sstevel@tonic-gate if(ui_method) 553*0Sstevel@tonic-gate { 554*0Sstevel@tonic-gate UI_destroy_method(ui_method); 555*0Sstevel@tonic-gate ui_method = NULL; 556*0Sstevel@tonic-gate } 557*0Sstevel@tonic-gate } 558*0Sstevel@tonic-gate int password_callback(char *buf, int bufsiz, int verify, 559*0Sstevel@tonic-gate PW_CB_DATA *cb_tmp) 560*0Sstevel@tonic-gate { 561*0Sstevel@tonic-gate UI *ui = NULL; 562*0Sstevel@tonic-gate int res = 0; 563*0Sstevel@tonic-gate const char *prompt_info = NULL; 564*0Sstevel@tonic-gate const char *password = NULL; 565*0Sstevel@tonic-gate PW_CB_DATA *cb_data = (PW_CB_DATA *)cb_tmp; 566*0Sstevel@tonic-gate 567*0Sstevel@tonic-gate if (cb_data) 568*0Sstevel@tonic-gate { 569*0Sstevel@tonic-gate if (cb_data->password) 570*0Sstevel@tonic-gate password = cb_data->password; 571*0Sstevel@tonic-gate if (cb_data->prompt_info) 572*0Sstevel@tonic-gate prompt_info = cb_data->prompt_info; 573*0Sstevel@tonic-gate } 574*0Sstevel@tonic-gate 575*0Sstevel@tonic-gate if (password) 576*0Sstevel@tonic-gate { 577*0Sstevel@tonic-gate res = strlen(password); 578*0Sstevel@tonic-gate if (res > bufsiz) 579*0Sstevel@tonic-gate res = bufsiz; 580*0Sstevel@tonic-gate memcpy(buf, password, res); 581*0Sstevel@tonic-gate return res; 582*0Sstevel@tonic-gate } 583*0Sstevel@tonic-gate 584*0Sstevel@tonic-gate ui = UI_new_method(ui_method); 585*0Sstevel@tonic-gate if (ui) 586*0Sstevel@tonic-gate { 587*0Sstevel@tonic-gate int ok = 0; 588*0Sstevel@tonic-gate char *buff = NULL; 589*0Sstevel@tonic-gate int ui_flags = 0; 590*0Sstevel@tonic-gate char *prompt = NULL; 591*0Sstevel@tonic-gate 592*0Sstevel@tonic-gate prompt = UI_construct_prompt(ui, "pass phrase", 593*0Sstevel@tonic-gate cb_data->prompt_info); 594*0Sstevel@tonic-gate 595*0Sstevel@tonic-gate ui_flags |= UI_INPUT_FLAG_DEFAULT_PWD; 596*0Sstevel@tonic-gate UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0); 597*0Sstevel@tonic-gate 598*0Sstevel@tonic-gate if (ok >= 0) 599*0Sstevel@tonic-gate ok = UI_add_input_string(ui,prompt,ui_flags,buf, 600*0Sstevel@tonic-gate PW_MIN_LENGTH,BUFSIZ-1); 601*0Sstevel@tonic-gate if (ok >= 0 && verify) 602*0Sstevel@tonic-gate { 603*0Sstevel@tonic-gate buff = (char *)OPENSSL_malloc(bufsiz); 604*0Sstevel@tonic-gate ok = UI_add_verify_string(ui,prompt,ui_flags,buff, 605*0Sstevel@tonic-gate PW_MIN_LENGTH,BUFSIZ-1, buf); 606*0Sstevel@tonic-gate } 607*0Sstevel@tonic-gate if (ok >= 0) 608*0Sstevel@tonic-gate do 609*0Sstevel@tonic-gate { 610*0Sstevel@tonic-gate ok = UI_process(ui); 611*0Sstevel@tonic-gate } 612*0Sstevel@tonic-gate while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0)); 613*0Sstevel@tonic-gate 614*0Sstevel@tonic-gate if (buff) 615*0Sstevel@tonic-gate { 616*0Sstevel@tonic-gate OPENSSL_cleanse(buff,(unsigned int)bufsiz); 617*0Sstevel@tonic-gate OPENSSL_free(buff); 618*0Sstevel@tonic-gate } 619*0Sstevel@tonic-gate 620*0Sstevel@tonic-gate if (ok >= 0) 621*0Sstevel@tonic-gate res = strlen(buf); 622*0Sstevel@tonic-gate if (ok == -1) 623*0Sstevel@tonic-gate { 624*0Sstevel@tonic-gate BIO_printf(bio_err, "User interface error\n"); 625*0Sstevel@tonic-gate ERR_print_errors(bio_err); 626*0Sstevel@tonic-gate OPENSSL_cleanse(buf,(unsigned int)bufsiz); 627*0Sstevel@tonic-gate res = 0; 628*0Sstevel@tonic-gate } 629*0Sstevel@tonic-gate if (ok == -2) 630*0Sstevel@tonic-gate { 631*0Sstevel@tonic-gate BIO_printf(bio_err,"aborted!\n"); 632*0Sstevel@tonic-gate OPENSSL_cleanse(buf,(unsigned int)bufsiz); 633*0Sstevel@tonic-gate res = 0; 634*0Sstevel@tonic-gate } 635*0Sstevel@tonic-gate UI_free(ui); 636*0Sstevel@tonic-gate OPENSSL_free(prompt); 637*0Sstevel@tonic-gate } 638*0Sstevel@tonic-gate return res; 639*0Sstevel@tonic-gate } 640*0Sstevel@tonic-gate 641*0Sstevel@tonic-gate static char *app_get_pass(BIO *err, char *arg, int keepbio); 642*0Sstevel@tonic-gate 643*0Sstevel@tonic-gate int app_passwd(BIO *err, char *arg1, char *arg2, char **pass1, char **pass2) 644*0Sstevel@tonic-gate { 645*0Sstevel@tonic-gate int same; 646*0Sstevel@tonic-gate if(!arg2 || !arg1 || strcmp(arg1, arg2)) same = 0; 647*0Sstevel@tonic-gate else same = 1; 648*0Sstevel@tonic-gate if(arg1) { 649*0Sstevel@tonic-gate *pass1 = app_get_pass(err, arg1, same); 650*0Sstevel@tonic-gate if(!*pass1) return 0; 651*0Sstevel@tonic-gate } else if(pass1) *pass1 = NULL; 652*0Sstevel@tonic-gate if(arg2) { 653*0Sstevel@tonic-gate *pass2 = app_get_pass(err, arg2, same ? 2 : 0); 654*0Sstevel@tonic-gate if(!*pass2) return 0; 655*0Sstevel@tonic-gate } else if(pass2) *pass2 = NULL; 656*0Sstevel@tonic-gate return 1; 657*0Sstevel@tonic-gate } 658*0Sstevel@tonic-gate 659*0Sstevel@tonic-gate static char *app_get_pass(BIO *err, char *arg, int keepbio) 660*0Sstevel@tonic-gate { 661*0Sstevel@tonic-gate char *tmp, tpass[APP_PASS_LEN]; 662*0Sstevel@tonic-gate static BIO *pwdbio = NULL; 663*0Sstevel@tonic-gate int i; 664*0Sstevel@tonic-gate if(!strncmp(arg, "pass:", 5)) return BUF_strdup(arg + 5); 665*0Sstevel@tonic-gate if(!strncmp(arg, "env:", 4)) { 666*0Sstevel@tonic-gate tmp = getenv(arg + 4); 667*0Sstevel@tonic-gate if(!tmp) { 668*0Sstevel@tonic-gate BIO_printf(err, "Can't read environment variable %s\n", arg + 4); 669*0Sstevel@tonic-gate return NULL; 670*0Sstevel@tonic-gate } 671*0Sstevel@tonic-gate return BUF_strdup(tmp); 672*0Sstevel@tonic-gate } 673*0Sstevel@tonic-gate if(!keepbio || !pwdbio) { 674*0Sstevel@tonic-gate if(!strncmp(arg, "file:", 5)) { 675*0Sstevel@tonic-gate pwdbio = BIO_new_file(arg + 5, "r"); 676*0Sstevel@tonic-gate if(!pwdbio) { 677*0Sstevel@tonic-gate BIO_printf(err, "Can't open file %s\n", arg + 5); 678*0Sstevel@tonic-gate return NULL; 679*0Sstevel@tonic-gate } 680*0Sstevel@tonic-gate } else if(!strncmp(arg, "fd:", 3)) { 681*0Sstevel@tonic-gate BIO *btmp; 682*0Sstevel@tonic-gate i = atoi(arg + 3); 683*0Sstevel@tonic-gate if(i >= 0) pwdbio = BIO_new_fd(i, BIO_NOCLOSE); 684*0Sstevel@tonic-gate if((i < 0) || !pwdbio) { 685*0Sstevel@tonic-gate BIO_printf(err, "Can't access file descriptor %s\n", arg + 3); 686*0Sstevel@tonic-gate return NULL; 687*0Sstevel@tonic-gate } 688*0Sstevel@tonic-gate /* Can't do BIO_gets on an fd BIO so add a buffering BIO */ 689*0Sstevel@tonic-gate btmp = BIO_new(BIO_f_buffer()); 690*0Sstevel@tonic-gate pwdbio = BIO_push(btmp, pwdbio); 691*0Sstevel@tonic-gate } else if(!strcmp(arg, "stdin")) { 692*0Sstevel@tonic-gate pwdbio = BIO_new_fp(stdin, BIO_NOCLOSE); 693*0Sstevel@tonic-gate if(!pwdbio) { 694*0Sstevel@tonic-gate BIO_printf(err, "Can't open BIO for stdin\n"); 695*0Sstevel@tonic-gate return NULL; 696*0Sstevel@tonic-gate } 697*0Sstevel@tonic-gate } else { 698*0Sstevel@tonic-gate BIO_printf(err, "Invalid password argument \"%s\"\n", arg); 699*0Sstevel@tonic-gate return NULL; 700*0Sstevel@tonic-gate } 701*0Sstevel@tonic-gate } 702*0Sstevel@tonic-gate i = BIO_gets(pwdbio, tpass, APP_PASS_LEN); 703*0Sstevel@tonic-gate if(keepbio != 1) { 704*0Sstevel@tonic-gate BIO_free_all(pwdbio); 705*0Sstevel@tonic-gate pwdbio = NULL; 706*0Sstevel@tonic-gate } 707*0Sstevel@tonic-gate if(i <= 0) { 708*0Sstevel@tonic-gate BIO_printf(err, "Error reading password from BIO\n"); 709*0Sstevel@tonic-gate return NULL; 710*0Sstevel@tonic-gate } 711*0Sstevel@tonic-gate tmp = strchr(tpass, '\n'); 712*0Sstevel@tonic-gate if(tmp) *tmp = 0; 713*0Sstevel@tonic-gate return BUF_strdup(tpass); 714*0Sstevel@tonic-gate } 715*0Sstevel@tonic-gate 716*0Sstevel@tonic-gate int add_oid_section(BIO *err, CONF *conf) 717*0Sstevel@tonic-gate { 718*0Sstevel@tonic-gate char *p; 719*0Sstevel@tonic-gate STACK_OF(CONF_VALUE) *sktmp; 720*0Sstevel@tonic-gate CONF_VALUE *cnf; 721*0Sstevel@tonic-gate int i; 722*0Sstevel@tonic-gate if(!(p=NCONF_get_string(conf,NULL,"oid_section"))) 723*0Sstevel@tonic-gate { 724*0Sstevel@tonic-gate ERR_clear_error(); 725*0Sstevel@tonic-gate return 1; 726*0Sstevel@tonic-gate } 727*0Sstevel@tonic-gate if(!(sktmp = NCONF_get_section(conf, p))) { 728*0Sstevel@tonic-gate BIO_printf(err, "problem loading oid section %s\n", p); 729*0Sstevel@tonic-gate return 0; 730*0Sstevel@tonic-gate } 731*0Sstevel@tonic-gate for(i = 0; i < sk_CONF_VALUE_num(sktmp); i++) { 732*0Sstevel@tonic-gate cnf = sk_CONF_VALUE_value(sktmp, i); 733*0Sstevel@tonic-gate if(OBJ_create(cnf->value, cnf->name, cnf->name) == NID_undef) { 734*0Sstevel@tonic-gate BIO_printf(err, "problem creating object %s=%s\n", 735*0Sstevel@tonic-gate cnf->name, cnf->value); 736*0Sstevel@tonic-gate return 0; 737*0Sstevel@tonic-gate } 738*0Sstevel@tonic-gate } 739*0Sstevel@tonic-gate return 1; 740*0Sstevel@tonic-gate } 741*0Sstevel@tonic-gate 742*0Sstevel@tonic-gate X509 *load_cert(BIO *err, const char *file, int format, 743*0Sstevel@tonic-gate const char *pass, ENGINE *e, const char *cert_descrip) 744*0Sstevel@tonic-gate { 745*0Sstevel@tonic-gate ASN1_HEADER *ah=NULL; 746*0Sstevel@tonic-gate BUF_MEM *buf=NULL; 747*0Sstevel@tonic-gate X509 *x=NULL; 748*0Sstevel@tonic-gate BIO *cert; 749*0Sstevel@tonic-gate 750*0Sstevel@tonic-gate if ((cert=BIO_new(BIO_s_file())) == NULL) 751*0Sstevel@tonic-gate { 752*0Sstevel@tonic-gate ERR_print_errors(err); 753*0Sstevel@tonic-gate goto end; 754*0Sstevel@tonic-gate } 755*0Sstevel@tonic-gate 756*0Sstevel@tonic-gate if (file == NULL) 757*0Sstevel@tonic-gate { 758*0Sstevel@tonic-gate setvbuf(stdin, NULL, _IONBF, 0); 759*0Sstevel@tonic-gate BIO_set_fp(cert,stdin,BIO_NOCLOSE); 760*0Sstevel@tonic-gate } 761*0Sstevel@tonic-gate else 762*0Sstevel@tonic-gate { 763*0Sstevel@tonic-gate if (BIO_read_filename(cert,file) <= 0) 764*0Sstevel@tonic-gate { 765*0Sstevel@tonic-gate BIO_printf(err, "Error opening %s %s\n", 766*0Sstevel@tonic-gate cert_descrip, file); 767*0Sstevel@tonic-gate ERR_print_errors(err); 768*0Sstevel@tonic-gate goto end; 769*0Sstevel@tonic-gate } 770*0Sstevel@tonic-gate } 771*0Sstevel@tonic-gate 772*0Sstevel@tonic-gate if (format == FORMAT_ASN1) 773*0Sstevel@tonic-gate x=d2i_X509_bio(cert,NULL); 774*0Sstevel@tonic-gate else if (format == FORMAT_NETSCAPE) 775*0Sstevel@tonic-gate { 776*0Sstevel@tonic-gate unsigned char *p,*op; 777*0Sstevel@tonic-gate int size=0,i; 778*0Sstevel@tonic-gate 779*0Sstevel@tonic-gate /* We sort of have to do it this way because it is sort of nice 780*0Sstevel@tonic-gate * to read the header first and check it, then 781*0Sstevel@tonic-gate * try to read the certificate */ 782*0Sstevel@tonic-gate buf=BUF_MEM_new(); 783*0Sstevel@tonic-gate for (;;) 784*0Sstevel@tonic-gate { 785*0Sstevel@tonic-gate if ((buf == NULL) || (!BUF_MEM_grow(buf,size+1024*10))) 786*0Sstevel@tonic-gate goto end; 787*0Sstevel@tonic-gate i=BIO_read(cert,&(buf->data[size]),1024*10); 788*0Sstevel@tonic-gate size+=i; 789*0Sstevel@tonic-gate if (i == 0) break; 790*0Sstevel@tonic-gate if (i < 0) 791*0Sstevel@tonic-gate { 792*0Sstevel@tonic-gate perror("reading certificate"); 793*0Sstevel@tonic-gate goto end; 794*0Sstevel@tonic-gate } 795*0Sstevel@tonic-gate } 796*0Sstevel@tonic-gate p=(unsigned char *)buf->data; 797*0Sstevel@tonic-gate op=p; 798*0Sstevel@tonic-gate 799*0Sstevel@tonic-gate /* First load the header */ 800*0Sstevel@tonic-gate if ((ah=d2i_ASN1_HEADER(NULL,&p,(long)size)) == NULL) 801*0Sstevel@tonic-gate goto end; 802*0Sstevel@tonic-gate if ((ah->header == NULL) || (ah->header->data == NULL) || 803*0Sstevel@tonic-gate (strncmp(NETSCAPE_CERT_HDR,(char *)ah->header->data, 804*0Sstevel@tonic-gate ah->header->length) != 0)) 805*0Sstevel@tonic-gate { 806*0Sstevel@tonic-gate BIO_printf(err,"Error reading header on certificate\n"); 807*0Sstevel@tonic-gate goto end; 808*0Sstevel@tonic-gate } 809*0Sstevel@tonic-gate /* header is ok, so now read the object */ 810*0Sstevel@tonic-gate p=op; 811*0Sstevel@tonic-gate ah->meth=X509_asn1_meth(); 812*0Sstevel@tonic-gate if ((ah=d2i_ASN1_HEADER(&ah,&p,(long)size)) == NULL) 813*0Sstevel@tonic-gate goto end; 814*0Sstevel@tonic-gate x=(X509 *)ah->data; 815*0Sstevel@tonic-gate ah->data=NULL; 816*0Sstevel@tonic-gate } 817*0Sstevel@tonic-gate else if (format == FORMAT_PEM) 818*0Sstevel@tonic-gate x=PEM_read_bio_X509_AUX(cert,NULL, 819*0Sstevel@tonic-gate (pem_password_cb *)password_callback, NULL); 820*0Sstevel@tonic-gate else if (format == FORMAT_PKCS12) 821*0Sstevel@tonic-gate { 822*0Sstevel@tonic-gate PKCS12 *p12 = d2i_PKCS12_bio(cert, NULL); 823*0Sstevel@tonic-gate 824*0Sstevel@tonic-gate PKCS12_parse(p12, NULL, NULL, &x, NULL); 825*0Sstevel@tonic-gate PKCS12_free(p12); 826*0Sstevel@tonic-gate p12 = NULL; 827*0Sstevel@tonic-gate } 828*0Sstevel@tonic-gate else { 829*0Sstevel@tonic-gate BIO_printf(err,"bad input format specified for %s\n", 830*0Sstevel@tonic-gate cert_descrip); 831*0Sstevel@tonic-gate goto end; 832*0Sstevel@tonic-gate } 833*0Sstevel@tonic-gate end: 834*0Sstevel@tonic-gate if (x == NULL) 835*0Sstevel@tonic-gate { 836*0Sstevel@tonic-gate BIO_printf(err,"unable to load certificate\n"); 837*0Sstevel@tonic-gate ERR_print_errors(err); 838*0Sstevel@tonic-gate } 839*0Sstevel@tonic-gate if (ah != NULL) ASN1_HEADER_free(ah); 840*0Sstevel@tonic-gate if (cert != NULL) BIO_free(cert); 841*0Sstevel@tonic-gate if (buf != NULL) BUF_MEM_free(buf); 842*0Sstevel@tonic-gate return(x); 843*0Sstevel@tonic-gate } 844*0Sstevel@tonic-gate 845*0Sstevel@tonic-gate EVP_PKEY *load_key(BIO *err, const char *file, int format, int maybe_stdin, 846*0Sstevel@tonic-gate const char *pass, ENGINE *e, const char *key_descrip) 847*0Sstevel@tonic-gate { 848*0Sstevel@tonic-gate BIO *key=NULL; 849*0Sstevel@tonic-gate EVP_PKEY *pkey=NULL; 850*0Sstevel@tonic-gate PW_CB_DATA cb_data; 851*0Sstevel@tonic-gate 852*0Sstevel@tonic-gate cb_data.password = pass; 853*0Sstevel@tonic-gate cb_data.prompt_info = file; 854*0Sstevel@tonic-gate 855*0Sstevel@tonic-gate if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE)) 856*0Sstevel@tonic-gate { 857*0Sstevel@tonic-gate BIO_printf(err,"no keyfile specified\n"); 858*0Sstevel@tonic-gate goto end; 859*0Sstevel@tonic-gate } 860*0Sstevel@tonic-gate #ifndef OPENSSL_NO_ENGINE 861*0Sstevel@tonic-gate if (format == FORMAT_ENGINE) 862*0Sstevel@tonic-gate { 863*0Sstevel@tonic-gate if (!e) 864*0Sstevel@tonic-gate BIO_printf(bio_err,"no engine specified\n"); 865*0Sstevel@tonic-gate else 866*0Sstevel@tonic-gate pkey = ENGINE_load_private_key(e, file, 867*0Sstevel@tonic-gate ui_method, &cb_data); 868*0Sstevel@tonic-gate goto end; 869*0Sstevel@tonic-gate } 870*0Sstevel@tonic-gate #endif 871*0Sstevel@tonic-gate key=BIO_new(BIO_s_file()); 872*0Sstevel@tonic-gate if (key == NULL) 873*0Sstevel@tonic-gate { 874*0Sstevel@tonic-gate ERR_print_errors(err); 875*0Sstevel@tonic-gate goto end; 876*0Sstevel@tonic-gate } 877*0Sstevel@tonic-gate if (file == NULL && maybe_stdin) 878*0Sstevel@tonic-gate { 879*0Sstevel@tonic-gate setvbuf(stdin, NULL, _IONBF, 0); 880*0Sstevel@tonic-gate BIO_set_fp(key,stdin,BIO_NOCLOSE); 881*0Sstevel@tonic-gate } 882*0Sstevel@tonic-gate else 883*0Sstevel@tonic-gate if (BIO_read_filename(key,file) <= 0) 884*0Sstevel@tonic-gate { 885*0Sstevel@tonic-gate BIO_printf(err, "Error opening %s %s\n", 886*0Sstevel@tonic-gate key_descrip, file); 887*0Sstevel@tonic-gate ERR_print_errors(err); 888*0Sstevel@tonic-gate goto end; 889*0Sstevel@tonic-gate } 890*0Sstevel@tonic-gate if (format == FORMAT_ASN1) 891*0Sstevel@tonic-gate { 892*0Sstevel@tonic-gate pkey=d2i_PrivateKey_bio(key, NULL); 893*0Sstevel@tonic-gate } 894*0Sstevel@tonic-gate else if (format == FORMAT_PEM) 895*0Sstevel@tonic-gate { 896*0Sstevel@tonic-gate pkey=PEM_read_bio_PrivateKey(key,NULL, 897*0Sstevel@tonic-gate (pem_password_cb *)password_callback, &cb_data); 898*0Sstevel@tonic-gate } 899*0Sstevel@tonic-gate #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA) 900*0Sstevel@tonic-gate else if (format == FORMAT_NETSCAPE || format == FORMAT_IISSGC) 901*0Sstevel@tonic-gate pkey = load_netscape_key(err, key, file, key_descrip, format); 902*0Sstevel@tonic-gate #endif 903*0Sstevel@tonic-gate else if (format == FORMAT_PKCS12) 904*0Sstevel@tonic-gate { 905*0Sstevel@tonic-gate PKCS12 *p12 = d2i_PKCS12_bio(key, NULL); 906*0Sstevel@tonic-gate 907*0Sstevel@tonic-gate PKCS12_parse(p12, pass, &pkey, NULL, NULL); 908*0Sstevel@tonic-gate PKCS12_free(p12); 909*0Sstevel@tonic-gate p12 = NULL; 910*0Sstevel@tonic-gate } 911*0Sstevel@tonic-gate else 912*0Sstevel@tonic-gate { 913*0Sstevel@tonic-gate BIO_printf(err,"bad input format specified for key file\n"); 914*0Sstevel@tonic-gate goto end; 915*0Sstevel@tonic-gate } 916*0Sstevel@tonic-gate end: 917*0Sstevel@tonic-gate if (key != NULL) BIO_free(key); 918*0Sstevel@tonic-gate if (pkey == NULL) 919*0Sstevel@tonic-gate BIO_printf(err,"unable to load %s\n", key_descrip); 920*0Sstevel@tonic-gate return(pkey); 921*0Sstevel@tonic-gate } 922*0Sstevel@tonic-gate 923*0Sstevel@tonic-gate EVP_PKEY *load_pubkey(BIO *err, const char *file, int format, int maybe_stdin, 924*0Sstevel@tonic-gate const char *pass, ENGINE *e, const char *key_descrip) 925*0Sstevel@tonic-gate { 926*0Sstevel@tonic-gate BIO *key=NULL; 927*0Sstevel@tonic-gate EVP_PKEY *pkey=NULL; 928*0Sstevel@tonic-gate PW_CB_DATA cb_data; 929*0Sstevel@tonic-gate 930*0Sstevel@tonic-gate cb_data.password = pass; 931*0Sstevel@tonic-gate cb_data.prompt_info = file; 932*0Sstevel@tonic-gate 933*0Sstevel@tonic-gate if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE)) 934*0Sstevel@tonic-gate { 935*0Sstevel@tonic-gate BIO_printf(err,"no keyfile specified\n"); 936*0Sstevel@tonic-gate goto end; 937*0Sstevel@tonic-gate } 938*0Sstevel@tonic-gate #ifndef OPENSSL_NO_ENGINE 939*0Sstevel@tonic-gate if (format == FORMAT_ENGINE) 940*0Sstevel@tonic-gate { 941*0Sstevel@tonic-gate if (!e) 942*0Sstevel@tonic-gate BIO_printf(bio_err,"no engine specified\n"); 943*0Sstevel@tonic-gate else 944*0Sstevel@tonic-gate pkey = ENGINE_load_public_key(e, file, 945*0Sstevel@tonic-gate ui_method, &cb_data); 946*0Sstevel@tonic-gate goto end; 947*0Sstevel@tonic-gate } 948*0Sstevel@tonic-gate #endif 949*0Sstevel@tonic-gate key=BIO_new(BIO_s_file()); 950*0Sstevel@tonic-gate if (key == NULL) 951*0Sstevel@tonic-gate { 952*0Sstevel@tonic-gate ERR_print_errors(err); 953*0Sstevel@tonic-gate goto end; 954*0Sstevel@tonic-gate } 955*0Sstevel@tonic-gate if (file == NULL && maybe_stdin) 956*0Sstevel@tonic-gate { 957*0Sstevel@tonic-gate setvbuf(stdin, NULL, _IONBF, 0); 958*0Sstevel@tonic-gate BIO_set_fp(key,stdin,BIO_NOCLOSE); 959*0Sstevel@tonic-gate } 960*0Sstevel@tonic-gate else 961*0Sstevel@tonic-gate if (BIO_read_filename(key,file) <= 0) 962*0Sstevel@tonic-gate { 963*0Sstevel@tonic-gate BIO_printf(err, "Error opening %s %s\n", 964*0Sstevel@tonic-gate key_descrip, file); 965*0Sstevel@tonic-gate ERR_print_errors(err); 966*0Sstevel@tonic-gate goto end; 967*0Sstevel@tonic-gate } 968*0Sstevel@tonic-gate if (format == FORMAT_ASN1) 969*0Sstevel@tonic-gate { 970*0Sstevel@tonic-gate pkey=d2i_PUBKEY_bio(key, NULL); 971*0Sstevel@tonic-gate } 972*0Sstevel@tonic-gate else if (format == FORMAT_PEM) 973*0Sstevel@tonic-gate { 974*0Sstevel@tonic-gate pkey=PEM_read_bio_PUBKEY(key,NULL, 975*0Sstevel@tonic-gate (pem_password_cb *)password_callback, &cb_data); 976*0Sstevel@tonic-gate } 977*0Sstevel@tonic-gate #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA) 978*0Sstevel@tonic-gate else if (format == FORMAT_NETSCAPE || format == FORMAT_IISSGC) 979*0Sstevel@tonic-gate pkey = load_netscape_key(err, key, file, key_descrip, format); 980*0Sstevel@tonic-gate #endif 981*0Sstevel@tonic-gate else 982*0Sstevel@tonic-gate { 983*0Sstevel@tonic-gate BIO_printf(err,"bad input format specified for key file\n"); 984*0Sstevel@tonic-gate goto end; 985*0Sstevel@tonic-gate } 986*0Sstevel@tonic-gate end: 987*0Sstevel@tonic-gate if (key != NULL) BIO_free(key); 988*0Sstevel@tonic-gate if (pkey == NULL) 989*0Sstevel@tonic-gate BIO_printf(err,"unable to load %s\n", key_descrip); 990*0Sstevel@tonic-gate return(pkey); 991*0Sstevel@tonic-gate } 992*0Sstevel@tonic-gate 993*0Sstevel@tonic-gate #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA) 994*0Sstevel@tonic-gate static EVP_PKEY * 995*0Sstevel@tonic-gate load_netscape_key(BIO *err, BIO *key, const char *file, 996*0Sstevel@tonic-gate const char *key_descrip, int format) 997*0Sstevel@tonic-gate { 998*0Sstevel@tonic-gate EVP_PKEY *pkey; 999*0Sstevel@tonic-gate BUF_MEM *buf; 1000*0Sstevel@tonic-gate RSA *rsa; 1001*0Sstevel@tonic-gate const unsigned char *p; 1002*0Sstevel@tonic-gate int size, i; 1003*0Sstevel@tonic-gate 1004*0Sstevel@tonic-gate buf=BUF_MEM_new(); 1005*0Sstevel@tonic-gate pkey = EVP_PKEY_new(); 1006*0Sstevel@tonic-gate size = 0; 1007*0Sstevel@tonic-gate if (buf == NULL || pkey == NULL) 1008*0Sstevel@tonic-gate goto error; 1009*0Sstevel@tonic-gate for (;;) 1010*0Sstevel@tonic-gate { 1011*0Sstevel@tonic-gate if (!BUF_MEM_grow_clean(buf,size+1024*10)) 1012*0Sstevel@tonic-gate goto error; 1013*0Sstevel@tonic-gate i = BIO_read(key, &(buf->data[size]), 1024*10); 1014*0Sstevel@tonic-gate size += i; 1015*0Sstevel@tonic-gate if (i == 0) 1016*0Sstevel@tonic-gate break; 1017*0Sstevel@tonic-gate if (i < 0) 1018*0Sstevel@tonic-gate { 1019*0Sstevel@tonic-gate BIO_printf(err, "Error reading %s %s", 1020*0Sstevel@tonic-gate key_descrip, file); 1021*0Sstevel@tonic-gate goto error; 1022*0Sstevel@tonic-gate } 1023*0Sstevel@tonic-gate } 1024*0Sstevel@tonic-gate p=(unsigned char *)buf->data; 1025*0Sstevel@tonic-gate rsa = d2i_RSA_NET(NULL,&p,(long)size,NULL, 1026*0Sstevel@tonic-gate (format == FORMAT_IISSGC ? 1 : 0)); 1027*0Sstevel@tonic-gate if (rsa == NULL) 1028*0Sstevel@tonic-gate goto error; 1029*0Sstevel@tonic-gate BUF_MEM_free(buf); 1030*0Sstevel@tonic-gate EVP_PKEY_set1_RSA(pkey, rsa); 1031*0Sstevel@tonic-gate return pkey; 1032*0Sstevel@tonic-gate error: 1033*0Sstevel@tonic-gate BUF_MEM_free(buf); 1034*0Sstevel@tonic-gate EVP_PKEY_free(pkey); 1035*0Sstevel@tonic-gate return NULL; 1036*0Sstevel@tonic-gate } 1037*0Sstevel@tonic-gate #endif /* ndef OPENSSL_NO_RC4 */ 1038*0Sstevel@tonic-gate 1039*0Sstevel@tonic-gate STACK_OF(X509) *load_certs(BIO *err, const char *file, int format, 1040*0Sstevel@tonic-gate const char *pass, ENGINE *e, const char *cert_descrip) 1041*0Sstevel@tonic-gate { 1042*0Sstevel@tonic-gate BIO *certs; 1043*0Sstevel@tonic-gate int i; 1044*0Sstevel@tonic-gate STACK_OF(X509) *othercerts = NULL; 1045*0Sstevel@tonic-gate STACK_OF(X509_INFO) *allcerts = NULL; 1046*0Sstevel@tonic-gate X509_INFO *xi; 1047*0Sstevel@tonic-gate PW_CB_DATA cb_data; 1048*0Sstevel@tonic-gate 1049*0Sstevel@tonic-gate cb_data.password = pass; 1050*0Sstevel@tonic-gate cb_data.prompt_info = file; 1051*0Sstevel@tonic-gate 1052*0Sstevel@tonic-gate if((certs = BIO_new(BIO_s_file())) == NULL) 1053*0Sstevel@tonic-gate { 1054*0Sstevel@tonic-gate ERR_print_errors(err); 1055*0Sstevel@tonic-gate goto end; 1056*0Sstevel@tonic-gate } 1057*0Sstevel@tonic-gate 1058*0Sstevel@tonic-gate if (file == NULL) 1059*0Sstevel@tonic-gate BIO_set_fp(certs,stdin,BIO_NOCLOSE); 1060*0Sstevel@tonic-gate else 1061*0Sstevel@tonic-gate { 1062*0Sstevel@tonic-gate if (BIO_read_filename(certs,file) <= 0) 1063*0Sstevel@tonic-gate { 1064*0Sstevel@tonic-gate BIO_printf(err, "Error opening %s %s\n", 1065*0Sstevel@tonic-gate cert_descrip, file); 1066*0Sstevel@tonic-gate ERR_print_errors(err); 1067*0Sstevel@tonic-gate goto end; 1068*0Sstevel@tonic-gate } 1069*0Sstevel@tonic-gate } 1070*0Sstevel@tonic-gate 1071*0Sstevel@tonic-gate if (format == FORMAT_PEM) 1072*0Sstevel@tonic-gate { 1073*0Sstevel@tonic-gate othercerts = sk_X509_new_null(); 1074*0Sstevel@tonic-gate if(!othercerts) 1075*0Sstevel@tonic-gate { 1076*0Sstevel@tonic-gate sk_X509_free(othercerts); 1077*0Sstevel@tonic-gate othercerts = NULL; 1078*0Sstevel@tonic-gate goto end; 1079*0Sstevel@tonic-gate } 1080*0Sstevel@tonic-gate allcerts = PEM_X509_INFO_read_bio(certs, NULL, 1081*0Sstevel@tonic-gate (pem_password_cb *)password_callback, &cb_data); 1082*0Sstevel@tonic-gate for(i = 0; i < sk_X509_INFO_num(allcerts); i++) 1083*0Sstevel@tonic-gate { 1084*0Sstevel@tonic-gate xi = sk_X509_INFO_value (allcerts, i); 1085*0Sstevel@tonic-gate if (xi->x509) 1086*0Sstevel@tonic-gate { 1087*0Sstevel@tonic-gate sk_X509_push(othercerts, xi->x509); 1088*0Sstevel@tonic-gate xi->x509 = NULL; 1089*0Sstevel@tonic-gate } 1090*0Sstevel@tonic-gate } 1091*0Sstevel@tonic-gate goto end; 1092*0Sstevel@tonic-gate } 1093*0Sstevel@tonic-gate else { 1094*0Sstevel@tonic-gate BIO_printf(err,"bad input format specified for %s\n", 1095*0Sstevel@tonic-gate cert_descrip); 1096*0Sstevel@tonic-gate goto end; 1097*0Sstevel@tonic-gate } 1098*0Sstevel@tonic-gate end: 1099*0Sstevel@tonic-gate if (othercerts == NULL) 1100*0Sstevel@tonic-gate { 1101*0Sstevel@tonic-gate BIO_printf(err,"unable to load certificates\n"); 1102*0Sstevel@tonic-gate ERR_print_errors(err); 1103*0Sstevel@tonic-gate } 1104*0Sstevel@tonic-gate if (allcerts) sk_X509_INFO_pop_free(allcerts, X509_INFO_free); 1105*0Sstevel@tonic-gate if (certs != NULL) BIO_free(certs); 1106*0Sstevel@tonic-gate return(othercerts); 1107*0Sstevel@tonic-gate } 1108*0Sstevel@tonic-gate 1109*0Sstevel@tonic-gate 1110*0Sstevel@tonic-gate #define X509V3_EXT_UNKNOWN_MASK (0xfL << 16) 1111*0Sstevel@tonic-gate /* Return error for unknown extensions */ 1112*0Sstevel@tonic-gate #define X509V3_EXT_DEFAULT 0 1113*0Sstevel@tonic-gate /* Print error for unknown extensions */ 1114*0Sstevel@tonic-gate #define X509V3_EXT_ERROR_UNKNOWN (1L << 16) 1115*0Sstevel@tonic-gate /* ASN1 parse unknown extensions */ 1116*0Sstevel@tonic-gate #define X509V3_EXT_PARSE_UNKNOWN (2L << 16) 1117*0Sstevel@tonic-gate /* BIO_dump unknown extensions */ 1118*0Sstevel@tonic-gate #define X509V3_EXT_DUMP_UNKNOWN (3L << 16) 1119*0Sstevel@tonic-gate 1120*0Sstevel@tonic-gate #define X509_FLAG_CA (X509_FLAG_NO_ISSUER | X509_FLAG_NO_PUBKEY | \ 1121*0Sstevel@tonic-gate X509_FLAG_NO_HEADER | X509_FLAG_NO_VERSION) 1122*0Sstevel@tonic-gate 1123*0Sstevel@tonic-gate int set_cert_ex(unsigned long *flags, const char *arg) 1124*0Sstevel@tonic-gate { 1125*0Sstevel@tonic-gate static const NAME_EX_TBL cert_tbl[] = { 1126*0Sstevel@tonic-gate { "compatible", X509_FLAG_COMPAT, 0xffffffffl}, 1127*0Sstevel@tonic-gate { "ca_default", X509_FLAG_CA, 0xffffffffl}, 1128*0Sstevel@tonic-gate { "no_header", X509_FLAG_NO_HEADER, 0}, 1129*0Sstevel@tonic-gate { "no_version", X509_FLAG_NO_VERSION, 0}, 1130*0Sstevel@tonic-gate { "no_serial", X509_FLAG_NO_SERIAL, 0}, 1131*0Sstevel@tonic-gate { "no_signame", X509_FLAG_NO_SIGNAME, 0}, 1132*0Sstevel@tonic-gate { "no_validity", X509_FLAG_NO_VALIDITY, 0}, 1133*0Sstevel@tonic-gate { "no_subject", X509_FLAG_NO_SUBJECT, 0}, 1134*0Sstevel@tonic-gate { "no_issuer", X509_FLAG_NO_ISSUER, 0}, 1135*0Sstevel@tonic-gate { "no_pubkey", X509_FLAG_NO_PUBKEY, 0}, 1136*0Sstevel@tonic-gate { "no_extensions", X509_FLAG_NO_EXTENSIONS, 0}, 1137*0Sstevel@tonic-gate { "no_sigdump", X509_FLAG_NO_SIGDUMP, 0}, 1138*0Sstevel@tonic-gate { "no_aux", X509_FLAG_NO_AUX, 0}, 1139*0Sstevel@tonic-gate { "no_attributes", X509_FLAG_NO_ATTRIBUTES, 0}, 1140*0Sstevel@tonic-gate { "ext_default", X509V3_EXT_DEFAULT, X509V3_EXT_UNKNOWN_MASK}, 1141*0Sstevel@tonic-gate { "ext_error", X509V3_EXT_ERROR_UNKNOWN, X509V3_EXT_UNKNOWN_MASK}, 1142*0Sstevel@tonic-gate { "ext_parse", X509V3_EXT_PARSE_UNKNOWN, X509V3_EXT_UNKNOWN_MASK}, 1143*0Sstevel@tonic-gate { "ext_dump", X509V3_EXT_DUMP_UNKNOWN, X509V3_EXT_UNKNOWN_MASK}, 1144*0Sstevel@tonic-gate { NULL, 0, 0} 1145*0Sstevel@tonic-gate }; 1146*0Sstevel@tonic-gate return set_multi_opts(flags, arg, cert_tbl); 1147*0Sstevel@tonic-gate } 1148*0Sstevel@tonic-gate 1149*0Sstevel@tonic-gate int set_name_ex(unsigned long *flags, const char *arg) 1150*0Sstevel@tonic-gate { 1151*0Sstevel@tonic-gate static const NAME_EX_TBL ex_tbl[] = { 1152*0Sstevel@tonic-gate { "esc_2253", ASN1_STRFLGS_ESC_2253, 0}, 1153*0Sstevel@tonic-gate { "esc_ctrl", ASN1_STRFLGS_ESC_CTRL, 0}, 1154*0Sstevel@tonic-gate { "esc_msb", ASN1_STRFLGS_ESC_MSB, 0}, 1155*0Sstevel@tonic-gate { "use_quote", ASN1_STRFLGS_ESC_QUOTE, 0}, 1156*0Sstevel@tonic-gate { "utf8", ASN1_STRFLGS_UTF8_CONVERT, 0}, 1157*0Sstevel@tonic-gate { "ignore_type", ASN1_STRFLGS_IGNORE_TYPE, 0}, 1158*0Sstevel@tonic-gate { "show_type", ASN1_STRFLGS_SHOW_TYPE, 0}, 1159*0Sstevel@tonic-gate { "dump_all", ASN1_STRFLGS_DUMP_ALL, 0}, 1160*0Sstevel@tonic-gate { "dump_nostr", ASN1_STRFLGS_DUMP_UNKNOWN, 0}, 1161*0Sstevel@tonic-gate { "dump_der", ASN1_STRFLGS_DUMP_DER, 0}, 1162*0Sstevel@tonic-gate { "compat", XN_FLAG_COMPAT, 0xffffffffL}, 1163*0Sstevel@tonic-gate { "sep_comma_plus", XN_FLAG_SEP_COMMA_PLUS, XN_FLAG_SEP_MASK}, 1164*0Sstevel@tonic-gate { "sep_comma_plus_space", XN_FLAG_SEP_CPLUS_SPC, XN_FLAG_SEP_MASK}, 1165*0Sstevel@tonic-gate { "sep_semi_plus_space", XN_FLAG_SEP_SPLUS_SPC, XN_FLAG_SEP_MASK}, 1166*0Sstevel@tonic-gate { "sep_multiline", XN_FLAG_SEP_MULTILINE, XN_FLAG_SEP_MASK}, 1167*0Sstevel@tonic-gate { "dn_rev", XN_FLAG_DN_REV, 0}, 1168*0Sstevel@tonic-gate { "nofname", XN_FLAG_FN_NONE, XN_FLAG_FN_MASK}, 1169*0Sstevel@tonic-gate { "sname", XN_FLAG_FN_SN, XN_FLAG_FN_MASK}, 1170*0Sstevel@tonic-gate { "lname", XN_FLAG_FN_LN, XN_FLAG_FN_MASK}, 1171*0Sstevel@tonic-gate { "align", XN_FLAG_FN_ALIGN, 0}, 1172*0Sstevel@tonic-gate { "oid", XN_FLAG_FN_OID, XN_FLAG_FN_MASK}, 1173*0Sstevel@tonic-gate { "space_eq", XN_FLAG_SPC_EQ, 0}, 1174*0Sstevel@tonic-gate { "dump_unknown", XN_FLAG_DUMP_UNKNOWN_FIELDS, 0}, 1175*0Sstevel@tonic-gate { "RFC2253", XN_FLAG_RFC2253, 0xffffffffL}, 1176*0Sstevel@tonic-gate { "oneline", XN_FLAG_ONELINE, 0xffffffffL}, 1177*0Sstevel@tonic-gate { "multiline", XN_FLAG_MULTILINE, 0xffffffffL}, 1178*0Sstevel@tonic-gate { "ca_default", XN_FLAG_MULTILINE, 0xffffffffL}, 1179*0Sstevel@tonic-gate { NULL, 0, 0} 1180*0Sstevel@tonic-gate }; 1181*0Sstevel@tonic-gate return set_multi_opts(flags, arg, ex_tbl); 1182*0Sstevel@tonic-gate } 1183*0Sstevel@tonic-gate 1184*0Sstevel@tonic-gate int set_ext_copy(int *copy_type, const char *arg) 1185*0Sstevel@tonic-gate { 1186*0Sstevel@tonic-gate if (!strcasecmp(arg, "none")) 1187*0Sstevel@tonic-gate *copy_type = EXT_COPY_NONE; 1188*0Sstevel@tonic-gate else if (!strcasecmp(arg, "copy")) 1189*0Sstevel@tonic-gate *copy_type = EXT_COPY_ADD; 1190*0Sstevel@tonic-gate else if (!strcasecmp(arg, "copyall")) 1191*0Sstevel@tonic-gate *copy_type = EXT_COPY_ALL; 1192*0Sstevel@tonic-gate else 1193*0Sstevel@tonic-gate return 0; 1194*0Sstevel@tonic-gate return 1; 1195*0Sstevel@tonic-gate } 1196*0Sstevel@tonic-gate 1197*0Sstevel@tonic-gate int copy_extensions(X509 *x, X509_REQ *req, int copy_type) 1198*0Sstevel@tonic-gate { 1199*0Sstevel@tonic-gate STACK_OF(X509_EXTENSION) *exts = NULL; 1200*0Sstevel@tonic-gate X509_EXTENSION *ext, *tmpext; 1201*0Sstevel@tonic-gate ASN1_OBJECT *obj; 1202*0Sstevel@tonic-gate int i, idx, ret = 0; 1203*0Sstevel@tonic-gate if (!x || !req || (copy_type == EXT_COPY_NONE)) 1204*0Sstevel@tonic-gate return 1; 1205*0Sstevel@tonic-gate exts = X509_REQ_get_extensions(req); 1206*0Sstevel@tonic-gate 1207*0Sstevel@tonic-gate for(i = 0; i < sk_X509_EXTENSION_num(exts); i++) { 1208*0Sstevel@tonic-gate ext = sk_X509_EXTENSION_value(exts, i); 1209*0Sstevel@tonic-gate obj = X509_EXTENSION_get_object(ext); 1210*0Sstevel@tonic-gate idx = X509_get_ext_by_OBJ(x, obj, -1); 1211*0Sstevel@tonic-gate /* Does extension exist? */ 1212*0Sstevel@tonic-gate if (idx != -1) { 1213*0Sstevel@tonic-gate /* If normal copy don't override existing extension */ 1214*0Sstevel@tonic-gate if (copy_type == EXT_COPY_ADD) 1215*0Sstevel@tonic-gate continue; 1216*0Sstevel@tonic-gate /* Delete all extensions of same type */ 1217*0Sstevel@tonic-gate do { 1218*0Sstevel@tonic-gate tmpext = X509_get_ext(x, idx); 1219*0Sstevel@tonic-gate X509_delete_ext(x, idx); 1220*0Sstevel@tonic-gate X509_EXTENSION_free(tmpext); 1221*0Sstevel@tonic-gate idx = X509_get_ext_by_OBJ(x, obj, -1); 1222*0Sstevel@tonic-gate } while (idx != -1); 1223*0Sstevel@tonic-gate } 1224*0Sstevel@tonic-gate if (!X509_add_ext(x, ext, -1)) 1225*0Sstevel@tonic-gate goto end; 1226*0Sstevel@tonic-gate } 1227*0Sstevel@tonic-gate 1228*0Sstevel@tonic-gate ret = 1; 1229*0Sstevel@tonic-gate 1230*0Sstevel@tonic-gate end: 1231*0Sstevel@tonic-gate 1232*0Sstevel@tonic-gate sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); 1233*0Sstevel@tonic-gate 1234*0Sstevel@tonic-gate return ret; 1235*0Sstevel@tonic-gate } 1236*0Sstevel@tonic-gate 1237*0Sstevel@tonic-gate 1238*0Sstevel@tonic-gate 1239*0Sstevel@tonic-gate 1240*0Sstevel@tonic-gate static int set_multi_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl) 1241*0Sstevel@tonic-gate { 1242*0Sstevel@tonic-gate STACK_OF(CONF_VALUE) *vals; 1243*0Sstevel@tonic-gate CONF_VALUE *val; 1244*0Sstevel@tonic-gate int i, ret = 1; 1245*0Sstevel@tonic-gate if(!arg) return 0; 1246*0Sstevel@tonic-gate vals = X509V3_parse_list(arg); 1247*0Sstevel@tonic-gate for (i = 0; i < sk_CONF_VALUE_num(vals); i++) { 1248*0Sstevel@tonic-gate val = sk_CONF_VALUE_value(vals, i); 1249*0Sstevel@tonic-gate if (!set_table_opts(flags, val->name, in_tbl)) 1250*0Sstevel@tonic-gate ret = 0; 1251*0Sstevel@tonic-gate } 1252*0Sstevel@tonic-gate sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); 1253*0Sstevel@tonic-gate return ret; 1254*0Sstevel@tonic-gate } 1255*0Sstevel@tonic-gate 1256*0Sstevel@tonic-gate static int set_table_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl) 1257*0Sstevel@tonic-gate { 1258*0Sstevel@tonic-gate char c; 1259*0Sstevel@tonic-gate const NAME_EX_TBL *ptbl; 1260*0Sstevel@tonic-gate c = arg[0]; 1261*0Sstevel@tonic-gate 1262*0Sstevel@tonic-gate if(c == '-') { 1263*0Sstevel@tonic-gate c = 0; 1264*0Sstevel@tonic-gate arg++; 1265*0Sstevel@tonic-gate } else if (c == '+') { 1266*0Sstevel@tonic-gate c = 1; 1267*0Sstevel@tonic-gate arg++; 1268*0Sstevel@tonic-gate } else c = 1; 1269*0Sstevel@tonic-gate 1270*0Sstevel@tonic-gate for(ptbl = in_tbl; ptbl->name; ptbl++) { 1271*0Sstevel@tonic-gate if(!strcasecmp(arg, ptbl->name)) { 1272*0Sstevel@tonic-gate *flags &= ~ptbl->mask; 1273*0Sstevel@tonic-gate if(c) *flags |= ptbl->flag; 1274*0Sstevel@tonic-gate else *flags &= ~ptbl->flag; 1275*0Sstevel@tonic-gate return 1; 1276*0Sstevel@tonic-gate } 1277*0Sstevel@tonic-gate } 1278*0Sstevel@tonic-gate return 0; 1279*0Sstevel@tonic-gate } 1280*0Sstevel@tonic-gate 1281*0Sstevel@tonic-gate void print_name(BIO *out, char *title, X509_NAME *nm, unsigned long lflags) 1282*0Sstevel@tonic-gate { 1283*0Sstevel@tonic-gate char *buf; 1284*0Sstevel@tonic-gate char mline = 0; 1285*0Sstevel@tonic-gate int indent = 0; 1286*0Sstevel@tonic-gate 1287*0Sstevel@tonic-gate if(title) BIO_puts(out, title); 1288*0Sstevel@tonic-gate if((lflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) { 1289*0Sstevel@tonic-gate mline = 1; 1290*0Sstevel@tonic-gate indent = 4; 1291*0Sstevel@tonic-gate } 1292*0Sstevel@tonic-gate if(lflags == XN_FLAG_COMPAT) { 1293*0Sstevel@tonic-gate buf = X509_NAME_oneline(nm, 0, 0); 1294*0Sstevel@tonic-gate BIO_puts(out, buf); 1295*0Sstevel@tonic-gate BIO_puts(out, "\n"); 1296*0Sstevel@tonic-gate OPENSSL_free(buf); 1297*0Sstevel@tonic-gate } else { 1298*0Sstevel@tonic-gate if(mline) BIO_puts(out, "\n"); 1299*0Sstevel@tonic-gate X509_NAME_print_ex(out, nm, indent, lflags); 1300*0Sstevel@tonic-gate BIO_puts(out, "\n"); 1301*0Sstevel@tonic-gate } 1302*0Sstevel@tonic-gate } 1303*0Sstevel@tonic-gate 1304*0Sstevel@tonic-gate X509_STORE *setup_verify(BIO *bp, char *CAfile, char *CApath) 1305*0Sstevel@tonic-gate { 1306*0Sstevel@tonic-gate X509_STORE *store; 1307*0Sstevel@tonic-gate X509_LOOKUP *lookup; 1308*0Sstevel@tonic-gate if(!(store = X509_STORE_new())) goto end; 1309*0Sstevel@tonic-gate lookup=X509_STORE_add_lookup(store,X509_LOOKUP_file()); 1310*0Sstevel@tonic-gate if (lookup == NULL) goto end; 1311*0Sstevel@tonic-gate if (CAfile) { 1312*0Sstevel@tonic-gate if(!X509_LOOKUP_load_file(lookup,CAfile,X509_FILETYPE_PEM)) { 1313*0Sstevel@tonic-gate BIO_printf(bp, "Error loading file %s\n", CAfile); 1314*0Sstevel@tonic-gate goto end; 1315*0Sstevel@tonic-gate } 1316*0Sstevel@tonic-gate } else X509_LOOKUP_load_file(lookup,NULL,X509_FILETYPE_DEFAULT); 1317*0Sstevel@tonic-gate 1318*0Sstevel@tonic-gate lookup=X509_STORE_add_lookup(store,X509_LOOKUP_hash_dir()); 1319*0Sstevel@tonic-gate if (lookup == NULL) goto end; 1320*0Sstevel@tonic-gate if (CApath) { 1321*0Sstevel@tonic-gate if(!X509_LOOKUP_add_dir(lookup,CApath,X509_FILETYPE_PEM)) { 1322*0Sstevel@tonic-gate BIO_printf(bp, "Error loading directory %s\n", CApath); 1323*0Sstevel@tonic-gate goto end; 1324*0Sstevel@tonic-gate } 1325*0Sstevel@tonic-gate } else X509_LOOKUP_add_dir(lookup,NULL,X509_FILETYPE_DEFAULT); 1326*0Sstevel@tonic-gate 1327*0Sstevel@tonic-gate ERR_clear_error(); 1328*0Sstevel@tonic-gate return store; 1329*0Sstevel@tonic-gate end: 1330*0Sstevel@tonic-gate X509_STORE_free(store); 1331*0Sstevel@tonic-gate return NULL; 1332*0Sstevel@tonic-gate } 1333*0Sstevel@tonic-gate 1334*0Sstevel@tonic-gate #ifndef OPENSSL_NO_ENGINE 1335*0Sstevel@tonic-gate /* Try to load an engine in a shareable library */ 1336*0Sstevel@tonic-gate static ENGINE *try_load_engine(BIO *err, const char *engine, int debug) 1337*0Sstevel@tonic-gate { 1338*0Sstevel@tonic-gate ENGINE *e = ENGINE_by_id("dynamic"); 1339*0Sstevel@tonic-gate if (e) 1340*0Sstevel@tonic-gate { 1341*0Sstevel@tonic-gate if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", engine, 0) 1342*0Sstevel@tonic-gate || !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0)) 1343*0Sstevel@tonic-gate { 1344*0Sstevel@tonic-gate ENGINE_free(e); 1345*0Sstevel@tonic-gate e = NULL; 1346*0Sstevel@tonic-gate } 1347*0Sstevel@tonic-gate } 1348*0Sstevel@tonic-gate return e; 1349*0Sstevel@tonic-gate } 1350*0Sstevel@tonic-gate 1351*0Sstevel@tonic-gate ENGINE *setup_engine(BIO *err, const char *engine, int debug) 1352*0Sstevel@tonic-gate { 1353*0Sstevel@tonic-gate ENGINE *e = NULL; 1354*0Sstevel@tonic-gate 1355*0Sstevel@tonic-gate if (engine) 1356*0Sstevel@tonic-gate { 1357*0Sstevel@tonic-gate if(strcmp(engine, "auto") == 0) 1358*0Sstevel@tonic-gate { 1359*0Sstevel@tonic-gate BIO_printf(err,"enabling auto ENGINE support\n"); 1360*0Sstevel@tonic-gate ENGINE_register_all_complete(); 1361*0Sstevel@tonic-gate return NULL; 1362*0Sstevel@tonic-gate } 1363*0Sstevel@tonic-gate if((e = ENGINE_by_id(engine)) == NULL 1364*0Sstevel@tonic-gate && (e = try_load_engine(err, engine, debug)) == NULL) 1365*0Sstevel@tonic-gate { 1366*0Sstevel@tonic-gate BIO_printf(err,"invalid engine \"%s\"\n", engine); 1367*0Sstevel@tonic-gate ERR_print_errors(err); 1368*0Sstevel@tonic-gate return NULL; 1369*0Sstevel@tonic-gate } 1370*0Sstevel@tonic-gate if (debug) 1371*0Sstevel@tonic-gate { 1372*0Sstevel@tonic-gate ENGINE_ctrl(e, ENGINE_CTRL_SET_LOGSTREAM, 1373*0Sstevel@tonic-gate 0, err, 0); 1374*0Sstevel@tonic-gate } 1375*0Sstevel@tonic-gate ENGINE_ctrl_cmd(e, "SET_USER_INTERFACE", 0, ui_method, 0, 1); 1376*0Sstevel@tonic-gate if(!ENGINE_set_default(e, ENGINE_METHOD_ALL)) 1377*0Sstevel@tonic-gate { 1378*0Sstevel@tonic-gate BIO_printf(err,"can't use that engine\n"); 1379*0Sstevel@tonic-gate ERR_print_errors(err); 1380*0Sstevel@tonic-gate ENGINE_free(e); 1381*0Sstevel@tonic-gate return NULL; 1382*0Sstevel@tonic-gate } 1383*0Sstevel@tonic-gate 1384*0Sstevel@tonic-gate BIO_printf(err,"engine \"%s\" set.\n", ENGINE_get_id(e)); 1385*0Sstevel@tonic-gate 1386*0Sstevel@tonic-gate /* Free our "structural" reference. */ 1387*0Sstevel@tonic-gate ENGINE_free(e); 1388*0Sstevel@tonic-gate } 1389*0Sstevel@tonic-gate return e; 1390*0Sstevel@tonic-gate } 1391*0Sstevel@tonic-gate #endif 1392*0Sstevel@tonic-gate 1393*0Sstevel@tonic-gate int load_config(BIO *err, CONF *cnf) 1394*0Sstevel@tonic-gate { 1395*0Sstevel@tonic-gate if (!cnf) 1396*0Sstevel@tonic-gate cnf = config; 1397*0Sstevel@tonic-gate if (!cnf) 1398*0Sstevel@tonic-gate return 1; 1399*0Sstevel@tonic-gate 1400*0Sstevel@tonic-gate OPENSSL_load_builtin_modules(); 1401*0Sstevel@tonic-gate 1402*0Sstevel@tonic-gate if (CONF_modules_load(cnf, NULL, 0) <= 0) 1403*0Sstevel@tonic-gate { 1404*0Sstevel@tonic-gate BIO_printf(err, "Error configuring OpenSSL\n"); 1405*0Sstevel@tonic-gate ERR_print_errors(err); 1406*0Sstevel@tonic-gate return 0; 1407*0Sstevel@tonic-gate } 1408*0Sstevel@tonic-gate return 1; 1409*0Sstevel@tonic-gate } 1410*0Sstevel@tonic-gate 1411*0Sstevel@tonic-gate char *make_config_name() 1412*0Sstevel@tonic-gate { 1413*0Sstevel@tonic-gate const char *t=X509_get_default_cert_area(); 1414*0Sstevel@tonic-gate size_t len; 1415*0Sstevel@tonic-gate char *p; 1416*0Sstevel@tonic-gate 1417*0Sstevel@tonic-gate len=strlen(t)+strlen(OPENSSL_CONF)+2; 1418*0Sstevel@tonic-gate p=OPENSSL_malloc(len); 1419*0Sstevel@tonic-gate BUF_strlcpy(p,t,len); 1420*0Sstevel@tonic-gate #ifndef OPENSSL_SYS_VMS 1421*0Sstevel@tonic-gate BUF_strlcat(p,"/",len); 1422*0Sstevel@tonic-gate #endif 1423*0Sstevel@tonic-gate BUF_strlcat(p,OPENSSL_CONF,len); 1424*0Sstevel@tonic-gate 1425*0Sstevel@tonic-gate return p; 1426*0Sstevel@tonic-gate } 1427*0Sstevel@tonic-gate 1428*0Sstevel@tonic-gate static unsigned long index_serial_hash(const char **a) 1429*0Sstevel@tonic-gate { 1430*0Sstevel@tonic-gate const char *n; 1431*0Sstevel@tonic-gate 1432*0Sstevel@tonic-gate n=a[DB_serial]; 1433*0Sstevel@tonic-gate while (*n == '0') n++; 1434*0Sstevel@tonic-gate return(lh_strhash(n)); 1435*0Sstevel@tonic-gate } 1436*0Sstevel@tonic-gate 1437*0Sstevel@tonic-gate static int index_serial_cmp(const char **a, const char **b) 1438*0Sstevel@tonic-gate { 1439*0Sstevel@tonic-gate const char *aa,*bb; 1440*0Sstevel@tonic-gate 1441*0Sstevel@tonic-gate for (aa=a[DB_serial]; *aa == '0'; aa++); 1442*0Sstevel@tonic-gate for (bb=b[DB_serial]; *bb == '0'; bb++); 1443*0Sstevel@tonic-gate return(strcmp(aa,bb)); 1444*0Sstevel@tonic-gate } 1445*0Sstevel@tonic-gate 1446*0Sstevel@tonic-gate static int index_name_qual(char **a) 1447*0Sstevel@tonic-gate { return(a[0][0] == 'V'); } 1448*0Sstevel@tonic-gate 1449*0Sstevel@tonic-gate static unsigned long index_name_hash(const char **a) 1450*0Sstevel@tonic-gate { return(lh_strhash(a[DB_name])); } 1451*0Sstevel@tonic-gate 1452*0Sstevel@tonic-gate int index_name_cmp(const char **a, const char **b) 1453*0Sstevel@tonic-gate { return(strcmp(a[DB_name], 1454*0Sstevel@tonic-gate b[DB_name])); } 1455*0Sstevel@tonic-gate 1456*0Sstevel@tonic-gate static IMPLEMENT_LHASH_HASH_FN(index_serial_hash,const char **) 1457*0Sstevel@tonic-gate static IMPLEMENT_LHASH_COMP_FN(index_serial_cmp,const char **) 1458*0Sstevel@tonic-gate static IMPLEMENT_LHASH_HASH_FN(index_name_hash,const char **) 1459*0Sstevel@tonic-gate static IMPLEMENT_LHASH_COMP_FN(index_name_cmp,const char **) 1460*0Sstevel@tonic-gate 1461*0Sstevel@tonic-gate #undef BSIZE 1462*0Sstevel@tonic-gate #define BSIZE 256 1463*0Sstevel@tonic-gate 1464*0Sstevel@tonic-gate BIGNUM *load_serial(char *serialfile, int create, ASN1_INTEGER **retai) 1465*0Sstevel@tonic-gate { 1466*0Sstevel@tonic-gate BIO *in=NULL; 1467*0Sstevel@tonic-gate BIGNUM *ret=NULL; 1468*0Sstevel@tonic-gate MS_STATIC char buf[1024]; 1469*0Sstevel@tonic-gate ASN1_INTEGER *ai=NULL; 1470*0Sstevel@tonic-gate 1471*0Sstevel@tonic-gate ai=ASN1_INTEGER_new(); 1472*0Sstevel@tonic-gate if (ai == NULL) goto err; 1473*0Sstevel@tonic-gate 1474*0Sstevel@tonic-gate if ((in=BIO_new(BIO_s_file())) == NULL) 1475*0Sstevel@tonic-gate { 1476*0Sstevel@tonic-gate ERR_print_errors(bio_err); 1477*0Sstevel@tonic-gate goto err; 1478*0Sstevel@tonic-gate } 1479*0Sstevel@tonic-gate 1480*0Sstevel@tonic-gate if (BIO_read_filename(in,serialfile) <= 0) 1481*0Sstevel@tonic-gate { 1482*0Sstevel@tonic-gate if (!create) 1483*0Sstevel@tonic-gate { 1484*0Sstevel@tonic-gate perror(serialfile); 1485*0Sstevel@tonic-gate goto err; 1486*0Sstevel@tonic-gate } 1487*0Sstevel@tonic-gate else 1488*0Sstevel@tonic-gate { 1489*0Sstevel@tonic-gate ASN1_INTEGER_set(ai,1); 1490*0Sstevel@tonic-gate ret=BN_new(); 1491*0Sstevel@tonic-gate if (ret == NULL) 1492*0Sstevel@tonic-gate BIO_printf(bio_err, "Out of memory\n"); 1493*0Sstevel@tonic-gate else 1494*0Sstevel@tonic-gate BN_one(ret); 1495*0Sstevel@tonic-gate } 1496*0Sstevel@tonic-gate } 1497*0Sstevel@tonic-gate else 1498*0Sstevel@tonic-gate { 1499*0Sstevel@tonic-gate if (!a2i_ASN1_INTEGER(in,ai,buf,1024)) 1500*0Sstevel@tonic-gate { 1501*0Sstevel@tonic-gate BIO_printf(bio_err,"unable to load number from %s\n", 1502*0Sstevel@tonic-gate serialfile); 1503*0Sstevel@tonic-gate goto err; 1504*0Sstevel@tonic-gate } 1505*0Sstevel@tonic-gate ret=ASN1_INTEGER_to_BN(ai,NULL); 1506*0Sstevel@tonic-gate if (ret == NULL) 1507*0Sstevel@tonic-gate { 1508*0Sstevel@tonic-gate BIO_printf(bio_err,"error converting number from bin to BIGNUM\n"); 1509*0Sstevel@tonic-gate goto err; 1510*0Sstevel@tonic-gate } 1511*0Sstevel@tonic-gate } 1512*0Sstevel@tonic-gate 1513*0Sstevel@tonic-gate if (ret && retai) 1514*0Sstevel@tonic-gate { 1515*0Sstevel@tonic-gate *retai = ai; 1516*0Sstevel@tonic-gate ai = NULL; 1517*0Sstevel@tonic-gate } 1518*0Sstevel@tonic-gate err: 1519*0Sstevel@tonic-gate if (in != NULL) BIO_free(in); 1520*0Sstevel@tonic-gate if (ai != NULL) ASN1_INTEGER_free(ai); 1521*0Sstevel@tonic-gate return(ret); 1522*0Sstevel@tonic-gate } 1523*0Sstevel@tonic-gate 1524*0Sstevel@tonic-gate int save_serial(char *serialfile, char *suffix, BIGNUM *serial, ASN1_INTEGER **retai) 1525*0Sstevel@tonic-gate { 1526*0Sstevel@tonic-gate char buf[1][BSIZE]; 1527*0Sstevel@tonic-gate BIO *out = NULL; 1528*0Sstevel@tonic-gate int ret=0; 1529*0Sstevel@tonic-gate ASN1_INTEGER *ai=NULL; 1530*0Sstevel@tonic-gate int j; 1531*0Sstevel@tonic-gate 1532*0Sstevel@tonic-gate if (suffix == NULL) 1533*0Sstevel@tonic-gate j = strlen(serialfile); 1534*0Sstevel@tonic-gate else 1535*0Sstevel@tonic-gate j = strlen(serialfile) + strlen(suffix) + 1; 1536*0Sstevel@tonic-gate if (j >= BSIZE) 1537*0Sstevel@tonic-gate { 1538*0Sstevel@tonic-gate BIO_printf(bio_err,"file name too long\n"); 1539*0Sstevel@tonic-gate goto err; 1540*0Sstevel@tonic-gate } 1541*0Sstevel@tonic-gate 1542*0Sstevel@tonic-gate if (suffix == NULL) 1543*0Sstevel@tonic-gate BUF_strlcpy(buf[0], serialfile, BSIZE); 1544*0Sstevel@tonic-gate else 1545*0Sstevel@tonic-gate { 1546*0Sstevel@tonic-gate #ifndef OPENSSL_SYS_VMS 1547*0Sstevel@tonic-gate j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", serialfile, suffix); 1548*0Sstevel@tonic-gate #else 1549*0Sstevel@tonic-gate j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", serialfile, suffix); 1550*0Sstevel@tonic-gate #endif 1551*0Sstevel@tonic-gate } 1552*0Sstevel@tonic-gate #ifdef RL_DEBUG 1553*0Sstevel@tonic-gate BIO_printf(bio_err, "DEBUG: writing \"%s\"\n", buf[0]); 1554*0Sstevel@tonic-gate #endif 1555*0Sstevel@tonic-gate out=BIO_new(BIO_s_file()); 1556*0Sstevel@tonic-gate if (out == NULL) 1557*0Sstevel@tonic-gate { 1558*0Sstevel@tonic-gate ERR_print_errors(bio_err); 1559*0Sstevel@tonic-gate goto err; 1560*0Sstevel@tonic-gate } 1561*0Sstevel@tonic-gate if (BIO_write_filename(out,buf[0]) <= 0) 1562*0Sstevel@tonic-gate { 1563*0Sstevel@tonic-gate perror(serialfile); 1564*0Sstevel@tonic-gate goto err; 1565*0Sstevel@tonic-gate } 1566*0Sstevel@tonic-gate 1567*0Sstevel@tonic-gate if ((ai=BN_to_ASN1_INTEGER(serial,NULL)) == NULL) 1568*0Sstevel@tonic-gate { 1569*0Sstevel@tonic-gate BIO_printf(bio_err,"error converting serial to ASN.1 format\n"); 1570*0Sstevel@tonic-gate goto err; 1571*0Sstevel@tonic-gate } 1572*0Sstevel@tonic-gate i2a_ASN1_INTEGER(out,ai); 1573*0Sstevel@tonic-gate BIO_puts(out,"\n"); 1574*0Sstevel@tonic-gate ret=1; 1575*0Sstevel@tonic-gate if (retai) 1576*0Sstevel@tonic-gate { 1577*0Sstevel@tonic-gate *retai = ai; 1578*0Sstevel@tonic-gate ai = NULL; 1579*0Sstevel@tonic-gate } 1580*0Sstevel@tonic-gate err: 1581*0Sstevel@tonic-gate if (out != NULL) BIO_free_all(out); 1582*0Sstevel@tonic-gate if (ai != NULL) ASN1_INTEGER_free(ai); 1583*0Sstevel@tonic-gate return(ret); 1584*0Sstevel@tonic-gate } 1585*0Sstevel@tonic-gate 1586*0Sstevel@tonic-gate int rotate_serial(char *serialfile, char *new_suffix, char *old_suffix) 1587*0Sstevel@tonic-gate { 1588*0Sstevel@tonic-gate char buf[5][BSIZE]; 1589*0Sstevel@tonic-gate int i,j; 1590*0Sstevel@tonic-gate struct stat sb; 1591*0Sstevel@tonic-gate 1592*0Sstevel@tonic-gate i = strlen(serialfile) + strlen(old_suffix); 1593*0Sstevel@tonic-gate j = strlen(serialfile) + strlen(new_suffix); 1594*0Sstevel@tonic-gate if (i > j) j = i; 1595*0Sstevel@tonic-gate if (j + 1 >= BSIZE) 1596*0Sstevel@tonic-gate { 1597*0Sstevel@tonic-gate BIO_printf(bio_err,"file name too long\n"); 1598*0Sstevel@tonic-gate goto err; 1599*0Sstevel@tonic-gate } 1600*0Sstevel@tonic-gate 1601*0Sstevel@tonic-gate #ifndef OPENSSL_SYS_VMS 1602*0Sstevel@tonic-gate j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", 1603*0Sstevel@tonic-gate serialfile, new_suffix); 1604*0Sstevel@tonic-gate #else 1605*0Sstevel@tonic-gate j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", 1606*0Sstevel@tonic-gate serialfile, new_suffix); 1607*0Sstevel@tonic-gate #endif 1608*0Sstevel@tonic-gate #ifndef OPENSSL_SYS_VMS 1609*0Sstevel@tonic-gate j = BIO_snprintf(buf[1], sizeof buf[1], "%s.%s", 1610*0Sstevel@tonic-gate serialfile, old_suffix); 1611*0Sstevel@tonic-gate #else 1612*0Sstevel@tonic-gate j = BIO_snprintf(buf[1], sizeof buf[1], "%s-%s", 1613*0Sstevel@tonic-gate serialfile, old_suffix); 1614*0Sstevel@tonic-gate #endif 1615*0Sstevel@tonic-gate if (stat(serialfile,&sb) < 0) 1616*0Sstevel@tonic-gate { 1617*0Sstevel@tonic-gate if (errno != ENOENT 1618*0Sstevel@tonic-gate #ifdef ENOTDIR 1619*0Sstevel@tonic-gate && errno != ENOTDIR) 1620*0Sstevel@tonic-gate #endif 1621*0Sstevel@tonic-gate goto err; 1622*0Sstevel@tonic-gate } 1623*0Sstevel@tonic-gate else 1624*0Sstevel@tonic-gate { 1625*0Sstevel@tonic-gate #ifdef RL_DEBUG 1626*0Sstevel@tonic-gate BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", 1627*0Sstevel@tonic-gate serialfile, buf[1]); 1628*0Sstevel@tonic-gate #endif 1629*0Sstevel@tonic-gate if (rename(serialfile,buf[1]) < 0) 1630*0Sstevel@tonic-gate { 1631*0Sstevel@tonic-gate BIO_printf(bio_err, 1632*0Sstevel@tonic-gate "unable to rename %s to %s\n", 1633*0Sstevel@tonic-gate serialfile, buf[1]); 1634*0Sstevel@tonic-gate perror("reason"); 1635*0Sstevel@tonic-gate goto err; 1636*0Sstevel@tonic-gate } 1637*0Sstevel@tonic-gate } 1638*0Sstevel@tonic-gate #ifdef RL_DEBUG 1639*0Sstevel@tonic-gate BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", 1640*0Sstevel@tonic-gate buf[0],serialfile); 1641*0Sstevel@tonic-gate #endif 1642*0Sstevel@tonic-gate if (rename(buf[0],serialfile) < 0) 1643*0Sstevel@tonic-gate { 1644*0Sstevel@tonic-gate BIO_printf(bio_err, 1645*0Sstevel@tonic-gate "unable to rename %s to %s\n", 1646*0Sstevel@tonic-gate buf[0],serialfile); 1647*0Sstevel@tonic-gate perror("reason"); 1648*0Sstevel@tonic-gate rename(buf[1],serialfile); 1649*0Sstevel@tonic-gate goto err; 1650*0Sstevel@tonic-gate } 1651*0Sstevel@tonic-gate return 1; 1652*0Sstevel@tonic-gate err: 1653*0Sstevel@tonic-gate return 0; 1654*0Sstevel@tonic-gate } 1655*0Sstevel@tonic-gate 1656*0Sstevel@tonic-gate CA_DB *load_index(char *dbfile, DB_ATTR *db_attr) 1657*0Sstevel@tonic-gate { 1658*0Sstevel@tonic-gate CA_DB *retdb = NULL; 1659*0Sstevel@tonic-gate TXT_DB *tmpdb = NULL; 1660*0Sstevel@tonic-gate BIO *in = BIO_new(BIO_s_file()); 1661*0Sstevel@tonic-gate CONF *dbattr_conf = NULL; 1662*0Sstevel@tonic-gate char buf[1][BSIZE]; 1663*0Sstevel@tonic-gate long errorline= -1; 1664*0Sstevel@tonic-gate 1665*0Sstevel@tonic-gate if (in == NULL) 1666*0Sstevel@tonic-gate { 1667*0Sstevel@tonic-gate ERR_print_errors(bio_err); 1668*0Sstevel@tonic-gate goto err; 1669*0Sstevel@tonic-gate } 1670*0Sstevel@tonic-gate if (BIO_read_filename(in,dbfile) <= 0) 1671*0Sstevel@tonic-gate { 1672*0Sstevel@tonic-gate perror(dbfile); 1673*0Sstevel@tonic-gate BIO_printf(bio_err,"unable to open '%s'\n",dbfile); 1674*0Sstevel@tonic-gate goto err; 1675*0Sstevel@tonic-gate } 1676*0Sstevel@tonic-gate if ((tmpdb = TXT_DB_read(in,DB_NUMBER)) == NULL) 1677*0Sstevel@tonic-gate { 1678*0Sstevel@tonic-gate if (tmpdb != NULL) TXT_DB_free(tmpdb); 1679*0Sstevel@tonic-gate goto err; 1680*0Sstevel@tonic-gate } 1681*0Sstevel@tonic-gate 1682*0Sstevel@tonic-gate #ifndef OPENSSL_SYS_VMS 1683*0Sstevel@tonic-gate BIO_snprintf(buf[0], sizeof buf[0], "%s.attr", dbfile); 1684*0Sstevel@tonic-gate #else 1685*0Sstevel@tonic-gate BIO_snprintf(buf[0], sizeof buf[0], "%s-attr", dbfile); 1686*0Sstevel@tonic-gate #endif 1687*0Sstevel@tonic-gate dbattr_conf = NCONF_new(NULL); 1688*0Sstevel@tonic-gate if (NCONF_load(dbattr_conf,buf[0],&errorline) <= 0) 1689*0Sstevel@tonic-gate { 1690*0Sstevel@tonic-gate if (errorline > 0) 1691*0Sstevel@tonic-gate { 1692*0Sstevel@tonic-gate BIO_printf(bio_err, 1693*0Sstevel@tonic-gate "error on line %ld of db attribute file '%s'\n" 1694*0Sstevel@tonic-gate ,errorline,buf[0]); 1695*0Sstevel@tonic-gate goto err; 1696*0Sstevel@tonic-gate } 1697*0Sstevel@tonic-gate else 1698*0Sstevel@tonic-gate { 1699*0Sstevel@tonic-gate NCONF_free(dbattr_conf); 1700*0Sstevel@tonic-gate dbattr_conf = NULL; 1701*0Sstevel@tonic-gate } 1702*0Sstevel@tonic-gate } 1703*0Sstevel@tonic-gate 1704*0Sstevel@tonic-gate if ((retdb = OPENSSL_malloc(sizeof(CA_DB))) == NULL) 1705*0Sstevel@tonic-gate { 1706*0Sstevel@tonic-gate fprintf(stderr, "Out of memory\n"); 1707*0Sstevel@tonic-gate goto err; 1708*0Sstevel@tonic-gate } 1709*0Sstevel@tonic-gate 1710*0Sstevel@tonic-gate retdb->db = tmpdb; 1711*0Sstevel@tonic-gate tmpdb = NULL; 1712*0Sstevel@tonic-gate if (db_attr) 1713*0Sstevel@tonic-gate retdb->attributes = *db_attr; 1714*0Sstevel@tonic-gate else 1715*0Sstevel@tonic-gate { 1716*0Sstevel@tonic-gate retdb->attributes.unique_subject = 1; 1717*0Sstevel@tonic-gate } 1718*0Sstevel@tonic-gate 1719*0Sstevel@tonic-gate if (dbattr_conf) 1720*0Sstevel@tonic-gate { 1721*0Sstevel@tonic-gate char *p = NCONF_get_string(dbattr_conf,NULL,"unique_subject"); 1722*0Sstevel@tonic-gate if (p) 1723*0Sstevel@tonic-gate { 1724*0Sstevel@tonic-gate BIO_printf(bio_err, "DEBUG[load_index]: unique_subject = \"%s\"\n", p); 1725*0Sstevel@tonic-gate switch(*p) 1726*0Sstevel@tonic-gate { 1727*0Sstevel@tonic-gate case 'f': /* false */ 1728*0Sstevel@tonic-gate case 'F': /* FALSE */ 1729*0Sstevel@tonic-gate case 'n': /* no */ 1730*0Sstevel@tonic-gate case 'N': /* NO */ 1731*0Sstevel@tonic-gate retdb->attributes.unique_subject = 0; 1732*0Sstevel@tonic-gate break; 1733*0Sstevel@tonic-gate case 't': /* true */ 1734*0Sstevel@tonic-gate case 'T': /* TRUE */ 1735*0Sstevel@tonic-gate case 'y': /* yes */ 1736*0Sstevel@tonic-gate case 'Y': /* YES */ 1737*0Sstevel@tonic-gate default: 1738*0Sstevel@tonic-gate retdb->attributes.unique_subject = 1; 1739*0Sstevel@tonic-gate break; 1740*0Sstevel@tonic-gate } 1741*0Sstevel@tonic-gate } 1742*0Sstevel@tonic-gate } 1743*0Sstevel@tonic-gate 1744*0Sstevel@tonic-gate err: 1745*0Sstevel@tonic-gate if (dbattr_conf) NCONF_free(dbattr_conf); 1746*0Sstevel@tonic-gate if (tmpdb) TXT_DB_free(tmpdb); 1747*0Sstevel@tonic-gate if (in) BIO_free_all(in); 1748*0Sstevel@tonic-gate return retdb; 1749*0Sstevel@tonic-gate } 1750*0Sstevel@tonic-gate 1751*0Sstevel@tonic-gate int index_index(CA_DB *db) 1752*0Sstevel@tonic-gate { 1753*0Sstevel@tonic-gate if (!TXT_DB_create_index(db->db, DB_serial, NULL, 1754*0Sstevel@tonic-gate LHASH_HASH_FN(index_serial_hash), 1755*0Sstevel@tonic-gate LHASH_COMP_FN(index_serial_cmp))) 1756*0Sstevel@tonic-gate { 1757*0Sstevel@tonic-gate BIO_printf(bio_err, 1758*0Sstevel@tonic-gate "error creating serial number index:(%ld,%ld,%ld)\n", 1759*0Sstevel@tonic-gate db->db->error,db->db->arg1,db->db->arg2); 1760*0Sstevel@tonic-gate return 0; 1761*0Sstevel@tonic-gate } 1762*0Sstevel@tonic-gate 1763*0Sstevel@tonic-gate if (db->attributes.unique_subject 1764*0Sstevel@tonic-gate && !TXT_DB_create_index(db->db, DB_name, index_name_qual, 1765*0Sstevel@tonic-gate LHASH_HASH_FN(index_name_hash), 1766*0Sstevel@tonic-gate LHASH_COMP_FN(index_name_cmp))) 1767*0Sstevel@tonic-gate { 1768*0Sstevel@tonic-gate BIO_printf(bio_err,"error creating name index:(%ld,%ld,%ld)\n", 1769*0Sstevel@tonic-gate db->db->error,db->db->arg1,db->db->arg2); 1770*0Sstevel@tonic-gate return 0; 1771*0Sstevel@tonic-gate } 1772*0Sstevel@tonic-gate return 1; 1773*0Sstevel@tonic-gate } 1774*0Sstevel@tonic-gate 1775*0Sstevel@tonic-gate int save_index(char *dbfile, char *suffix, CA_DB *db) 1776*0Sstevel@tonic-gate { 1777*0Sstevel@tonic-gate char buf[3][BSIZE]; 1778*0Sstevel@tonic-gate BIO *out = BIO_new(BIO_s_file()); 1779*0Sstevel@tonic-gate int j; 1780*0Sstevel@tonic-gate 1781*0Sstevel@tonic-gate if (out == NULL) 1782*0Sstevel@tonic-gate { 1783*0Sstevel@tonic-gate ERR_print_errors(bio_err); 1784*0Sstevel@tonic-gate goto err; 1785*0Sstevel@tonic-gate } 1786*0Sstevel@tonic-gate 1787*0Sstevel@tonic-gate j = strlen(dbfile) + strlen(suffix); 1788*0Sstevel@tonic-gate if (j + 6 >= BSIZE) 1789*0Sstevel@tonic-gate { 1790*0Sstevel@tonic-gate BIO_printf(bio_err,"file name too long\n"); 1791*0Sstevel@tonic-gate goto err; 1792*0Sstevel@tonic-gate } 1793*0Sstevel@tonic-gate 1794*0Sstevel@tonic-gate #ifndef OPENSSL_SYS_VMS 1795*0Sstevel@tonic-gate j = BIO_snprintf(buf[2], sizeof buf[2], "%s.attr", dbfile); 1796*0Sstevel@tonic-gate #else 1797*0Sstevel@tonic-gate j = BIO_snprintf(buf[2], sizeof buf[2], "%s-attr", dbfile); 1798*0Sstevel@tonic-gate #endif 1799*0Sstevel@tonic-gate #ifndef OPENSSL_SYS_VMS 1800*0Sstevel@tonic-gate j = BIO_snprintf(buf[1], sizeof buf[1], "%s.attr.%s", dbfile, suffix); 1801*0Sstevel@tonic-gate #else 1802*0Sstevel@tonic-gate j = BIO_snprintf(buf[1], sizeof buf[1], "%s-attr-%s", dbfile, suffix); 1803*0Sstevel@tonic-gate #endif 1804*0Sstevel@tonic-gate #ifndef OPENSSL_SYS_VMS 1805*0Sstevel@tonic-gate j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", dbfile, suffix); 1806*0Sstevel@tonic-gate #else 1807*0Sstevel@tonic-gate j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", dbfile, suffix); 1808*0Sstevel@tonic-gate #endif 1809*0Sstevel@tonic-gate #ifdef RL_DEBUG 1810*0Sstevel@tonic-gate BIO_printf(bio_err, "DEBUG: writing \"%s\"\n", buf[0]); 1811*0Sstevel@tonic-gate #endif 1812*0Sstevel@tonic-gate if (BIO_write_filename(out,buf[0]) <= 0) 1813*0Sstevel@tonic-gate { 1814*0Sstevel@tonic-gate perror(dbfile); 1815*0Sstevel@tonic-gate BIO_printf(bio_err,"unable to open '%s'\n", dbfile); 1816*0Sstevel@tonic-gate goto err; 1817*0Sstevel@tonic-gate } 1818*0Sstevel@tonic-gate j=TXT_DB_write(out,db->db); 1819*0Sstevel@tonic-gate if (j <= 0) goto err; 1820*0Sstevel@tonic-gate 1821*0Sstevel@tonic-gate BIO_free(out); 1822*0Sstevel@tonic-gate 1823*0Sstevel@tonic-gate out = BIO_new(BIO_s_file()); 1824*0Sstevel@tonic-gate #ifdef RL_DEBUG 1825*0Sstevel@tonic-gate BIO_printf(bio_err, "DEBUG: writing \"%s\"\n", buf[1]); 1826*0Sstevel@tonic-gate #endif 1827*0Sstevel@tonic-gate if (BIO_write_filename(out,buf[1]) <= 0) 1828*0Sstevel@tonic-gate { 1829*0Sstevel@tonic-gate perror(buf[2]); 1830*0Sstevel@tonic-gate BIO_printf(bio_err,"unable to open '%s'\n", buf[2]); 1831*0Sstevel@tonic-gate goto err; 1832*0Sstevel@tonic-gate } 1833*0Sstevel@tonic-gate BIO_printf(out,"unique_subject = %s\n", 1834*0Sstevel@tonic-gate db->attributes.unique_subject ? "yes" : "no"); 1835*0Sstevel@tonic-gate BIO_free(out); 1836*0Sstevel@tonic-gate 1837*0Sstevel@tonic-gate return 1; 1838*0Sstevel@tonic-gate err: 1839*0Sstevel@tonic-gate return 0; 1840*0Sstevel@tonic-gate } 1841*0Sstevel@tonic-gate 1842*0Sstevel@tonic-gate int rotate_index(char *dbfile, char *new_suffix, char *old_suffix) 1843*0Sstevel@tonic-gate { 1844*0Sstevel@tonic-gate char buf[5][BSIZE]; 1845*0Sstevel@tonic-gate int i,j; 1846*0Sstevel@tonic-gate struct stat sb; 1847*0Sstevel@tonic-gate 1848*0Sstevel@tonic-gate i = strlen(dbfile) + strlen(old_suffix); 1849*0Sstevel@tonic-gate j = strlen(dbfile) + strlen(new_suffix); 1850*0Sstevel@tonic-gate if (i > j) j = i; 1851*0Sstevel@tonic-gate if (j + 6 >= BSIZE) 1852*0Sstevel@tonic-gate { 1853*0Sstevel@tonic-gate BIO_printf(bio_err,"file name too long\n"); 1854*0Sstevel@tonic-gate goto err; 1855*0Sstevel@tonic-gate } 1856*0Sstevel@tonic-gate 1857*0Sstevel@tonic-gate #ifndef OPENSSL_SYS_VMS 1858*0Sstevel@tonic-gate j = BIO_snprintf(buf[4], sizeof buf[4], "%s.attr", dbfile); 1859*0Sstevel@tonic-gate #else 1860*0Sstevel@tonic-gate j = BIO_snprintf(buf[4], sizeof buf[4], "%s-attr", dbfile); 1861*0Sstevel@tonic-gate #endif 1862*0Sstevel@tonic-gate #ifndef OPENSSL_SYS_VMS 1863*0Sstevel@tonic-gate j = BIO_snprintf(buf[2], sizeof buf[2], "%s.attr.%s", 1864*0Sstevel@tonic-gate dbfile, new_suffix); 1865*0Sstevel@tonic-gate #else 1866*0Sstevel@tonic-gate j = BIO_snprintf(buf[2], sizeof buf[2], "%s-attr-%s", 1867*0Sstevel@tonic-gate dbfile, new_suffix); 1868*0Sstevel@tonic-gate #endif 1869*0Sstevel@tonic-gate #ifndef OPENSSL_SYS_VMS 1870*0Sstevel@tonic-gate j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", 1871*0Sstevel@tonic-gate dbfile, new_suffix); 1872*0Sstevel@tonic-gate #else 1873*0Sstevel@tonic-gate j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", 1874*0Sstevel@tonic-gate dbfile, new_suffix); 1875*0Sstevel@tonic-gate #endif 1876*0Sstevel@tonic-gate #ifndef OPENSSL_SYS_VMS 1877*0Sstevel@tonic-gate j = BIO_snprintf(buf[1], sizeof buf[1], "%s.%s", 1878*0Sstevel@tonic-gate dbfile, old_suffix); 1879*0Sstevel@tonic-gate #else 1880*0Sstevel@tonic-gate j = BIO_snprintf(buf[1], sizeof buf[1], "%s-%s", 1881*0Sstevel@tonic-gate dbfile, old_suffix); 1882*0Sstevel@tonic-gate #endif 1883*0Sstevel@tonic-gate #ifndef OPENSSL_SYS_VMS 1884*0Sstevel@tonic-gate j = BIO_snprintf(buf[3], sizeof buf[3], "%s.attr.%s", 1885*0Sstevel@tonic-gate dbfile, old_suffix); 1886*0Sstevel@tonic-gate #else 1887*0Sstevel@tonic-gate j = BIO_snprintf(buf[3], sizeof buf[3], "%s-attr-%s", 1888*0Sstevel@tonic-gate dbfile, old_suffix); 1889*0Sstevel@tonic-gate #endif 1890*0Sstevel@tonic-gate if (stat(dbfile,&sb) < 0) 1891*0Sstevel@tonic-gate { 1892*0Sstevel@tonic-gate if (errno != ENOENT 1893*0Sstevel@tonic-gate #ifdef ENOTDIR 1894*0Sstevel@tonic-gate && errno != ENOTDIR) 1895*0Sstevel@tonic-gate #endif 1896*0Sstevel@tonic-gate goto err; 1897*0Sstevel@tonic-gate } 1898*0Sstevel@tonic-gate else 1899*0Sstevel@tonic-gate { 1900*0Sstevel@tonic-gate #ifdef RL_DEBUG 1901*0Sstevel@tonic-gate BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", 1902*0Sstevel@tonic-gate dbfile, buf[1]); 1903*0Sstevel@tonic-gate #endif 1904*0Sstevel@tonic-gate if (rename(dbfile,buf[1]) < 0) 1905*0Sstevel@tonic-gate { 1906*0Sstevel@tonic-gate BIO_printf(bio_err, 1907*0Sstevel@tonic-gate "unable to rename %s to %s\n", 1908*0Sstevel@tonic-gate dbfile, buf[1]); 1909*0Sstevel@tonic-gate perror("reason"); 1910*0Sstevel@tonic-gate goto err; 1911*0Sstevel@tonic-gate } 1912*0Sstevel@tonic-gate } 1913*0Sstevel@tonic-gate #ifdef RL_DEBUG 1914*0Sstevel@tonic-gate BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", 1915*0Sstevel@tonic-gate buf[0],dbfile); 1916*0Sstevel@tonic-gate #endif 1917*0Sstevel@tonic-gate if (rename(buf[0],dbfile) < 0) 1918*0Sstevel@tonic-gate { 1919*0Sstevel@tonic-gate BIO_printf(bio_err, 1920*0Sstevel@tonic-gate "unable to rename %s to %s\n", 1921*0Sstevel@tonic-gate buf[0],dbfile); 1922*0Sstevel@tonic-gate perror("reason"); 1923*0Sstevel@tonic-gate rename(buf[1],dbfile); 1924*0Sstevel@tonic-gate goto err; 1925*0Sstevel@tonic-gate } 1926*0Sstevel@tonic-gate if (stat(buf[4],&sb) < 0) 1927*0Sstevel@tonic-gate { 1928*0Sstevel@tonic-gate if (errno != ENOENT 1929*0Sstevel@tonic-gate #ifdef ENOTDIR 1930*0Sstevel@tonic-gate && errno != ENOTDIR) 1931*0Sstevel@tonic-gate #endif 1932*0Sstevel@tonic-gate goto err; 1933*0Sstevel@tonic-gate } 1934*0Sstevel@tonic-gate else 1935*0Sstevel@tonic-gate { 1936*0Sstevel@tonic-gate #ifdef RL_DEBUG 1937*0Sstevel@tonic-gate BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", 1938*0Sstevel@tonic-gate buf[4],buf[3]); 1939*0Sstevel@tonic-gate #endif 1940*0Sstevel@tonic-gate if (rename(buf[4],buf[3]) < 0) 1941*0Sstevel@tonic-gate { 1942*0Sstevel@tonic-gate BIO_printf(bio_err, 1943*0Sstevel@tonic-gate "unable to rename %s to %s\n", 1944*0Sstevel@tonic-gate buf[4], buf[3]); 1945*0Sstevel@tonic-gate perror("reason"); 1946*0Sstevel@tonic-gate rename(dbfile,buf[0]); 1947*0Sstevel@tonic-gate rename(buf[1],dbfile); 1948*0Sstevel@tonic-gate goto err; 1949*0Sstevel@tonic-gate } 1950*0Sstevel@tonic-gate } 1951*0Sstevel@tonic-gate #ifdef RL_DEBUG 1952*0Sstevel@tonic-gate BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", 1953*0Sstevel@tonic-gate buf[2],buf[4]); 1954*0Sstevel@tonic-gate #endif 1955*0Sstevel@tonic-gate if (rename(buf[2],buf[4]) < 0) 1956*0Sstevel@tonic-gate { 1957*0Sstevel@tonic-gate BIO_printf(bio_err, 1958*0Sstevel@tonic-gate "unable to rename %s to %s\n", 1959*0Sstevel@tonic-gate buf[2],buf[4]); 1960*0Sstevel@tonic-gate perror("reason"); 1961*0Sstevel@tonic-gate rename(buf[3],buf[4]); 1962*0Sstevel@tonic-gate rename(dbfile,buf[0]); 1963*0Sstevel@tonic-gate rename(buf[1],dbfile); 1964*0Sstevel@tonic-gate goto err; 1965*0Sstevel@tonic-gate } 1966*0Sstevel@tonic-gate return 1; 1967*0Sstevel@tonic-gate err: 1968*0Sstevel@tonic-gate return 0; 1969*0Sstevel@tonic-gate } 1970*0Sstevel@tonic-gate 1971*0Sstevel@tonic-gate void free_index(CA_DB *db) 1972*0Sstevel@tonic-gate { 1973*0Sstevel@tonic-gate TXT_DB_free(db->db); 1974*0Sstevel@tonic-gate OPENSSL_free(db); 1975*0Sstevel@tonic-gate } 1976