1*ebfedea0SLionel Sambuc /* apps/apps.c */ 2*ebfedea0SLionel Sambuc /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3*ebfedea0SLionel Sambuc * All rights reserved. 4*ebfedea0SLionel Sambuc * 5*ebfedea0SLionel Sambuc * This package is an SSL implementation written 6*ebfedea0SLionel Sambuc * by Eric Young (eay@cryptsoft.com). 7*ebfedea0SLionel Sambuc * The implementation was written so as to conform with Netscapes SSL. 8*ebfedea0SLionel Sambuc * 9*ebfedea0SLionel Sambuc * This library is free for commercial and non-commercial use as long as 10*ebfedea0SLionel Sambuc * the following conditions are aheared to. The following conditions 11*ebfedea0SLionel Sambuc * apply to all code found in this distribution, be it the RC4, RSA, 12*ebfedea0SLionel Sambuc * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13*ebfedea0SLionel Sambuc * included with this distribution is covered by the same copyright terms 14*ebfedea0SLionel Sambuc * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15*ebfedea0SLionel Sambuc * 16*ebfedea0SLionel Sambuc * Copyright remains Eric Young's, and as such any Copyright notices in 17*ebfedea0SLionel Sambuc * the code are not to be removed. 18*ebfedea0SLionel Sambuc * If this package is used in a product, Eric Young should be given attribution 19*ebfedea0SLionel Sambuc * as the author of the parts of the library used. 20*ebfedea0SLionel Sambuc * This can be in the form of a textual message at program startup or 21*ebfedea0SLionel Sambuc * in documentation (online or textual) provided with the package. 22*ebfedea0SLionel Sambuc * 23*ebfedea0SLionel Sambuc * Redistribution and use in source and binary forms, with or without 24*ebfedea0SLionel Sambuc * modification, are permitted provided that the following conditions 25*ebfedea0SLionel Sambuc * are met: 26*ebfedea0SLionel Sambuc * 1. Redistributions of source code must retain the copyright 27*ebfedea0SLionel Sambuc * notice, this list of conditions and the following disclaimer. 28*ebfedea0SLionel Sambuc * 2. Redistributions in binary form must reproduce the above copyright 29*ebfedea0SLionel Sambuc * notice, this list of conditions and the following disclaimer in the 30*ebfedea0SLionel Sambuc * documentation and/or other materials provided with the distribution. 31*ebfedea0SLionel Sambuc * 3. All advertising materials mentioning features or use of this software 32*ebfedea0SLionel Sambuc * must display the following acknowledgement: 33*ebfedea0SLionel Sambuc * "This product includes cryptographic software written by 34*ebfedea0SLionel Sambuc * Eric Young (eay@cryptsoft.com)" 35*ebfedea0SLionel Sambuc * The word 'cryptographic' can be left out if the rouines from the library 36*ebfedea0SLionel Sambuc * being used are not cryptographic related :-). 37*ebfedea0SLionel Sambuc * 4. If you include any Windows specific code (or a derivative thereof) from 38*ebfedea0SLionel Sambuc * the apps directory (application code) you must include an acknowledgement: 39*ebfedea0SLionel Sambuc * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40*ebfedea0SLionel Sambuc * 41*ebfedea0SLionel Sambuc * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42*ebfedea0SLionel Sambuc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43*ebfedea0SLionel Sambuc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44*ebfedea0SLionel Sambuc * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45*ebfedea0SLionel Sambuc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46*ebfedea0SLionel Sambuc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47*ebfedea0SLionel Sambuc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48*ebfedea0SLionel Sambuc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49*ebfedea0SLionel Sambuc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50*ebfedea0SLionel Sambuc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51*ebfedea0SLionel Sambuc * SUCH DAMAGE. 52*ebfedea0SLionel Sambuc * 53*ebfedea0SLionel Sambuc * The licence and distribution terms for any publically available version or 54*ebfedea0SLionel Sambuc * derivative of this code cannot be changed. i.e. this code cannot simply be 55*ebfedea0SLionel Sambuc * copied and put under another distribution licence 56*ebfedea0SLionel Sambuc * [including the GNU Public Licence.] 57*ebfedea0SLionel Sambuc */ 58*ebfedea0SLionel Sambuc /* ==================================================================== 59*ebfedea0SLionel Sambuc * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. 60*ebfedea0SLionel Sambuc * 61*ebfedea0SLionel Sambuc * Redistribution and use in source and binary forms, with or without 62*ebfedea0SLionel Sambuc * modification, are permitted provided that the following conditions 63*ebfedea0SLionel Sambuc * are met: 64*ebfedea0SLionel Sambuc * 65*ebfedea0SLionel Sambuc * 1. Redistributions of source code must retain the above copyright 66*ebfedea0SLionel Sambuc * notice, this list of conditions and the following disclaimer. 67*ebfedea0SLionel Sambuc * 68*ebfedea0SLionel Sambuc * 2. Redistributions in binary form must reproduce the above copyright 69*ebfedea0SLionel Sambuc * notice, this list of conditions and the following disclaimer in 70*ebfedea0SLionel Sambuc * the documentation and/or other materials provided with the 71*ebfedea0SLionel Sambuc * distribution. 72*ebfedea0SLionel Sambuc * 73*ebfedea0SLionel Sambuc * 3. All advertising materials mentioning features or use of this 74*ebfedea0SLionel Sambuc * software must display the following acknowledgment: 75*ebfedea0SLionel Sambuc * "This product includes software developed by the OpenSSL Project 76*ebfedea0SLionel Sambuc * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 77*ebfedea0SLionel Sambuc * 78*ebfedea0SLionel Sambuc * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 79*ebfedea0SLionel Sambuc * endorse or promote products derived from this software without 80*ebfedea0SLionel Sambuc * prior written permission. For written permission, please contact 81*ebfedea0SLionel Sambuc * openssl-core@openssl.org. 82*ebfedea0SLionel Sambuc * 83*ebfedea0SLionel Sambuc * 5. Products derived from this software may not be called "OpenSSL" 84*ebfedea0SLionel Sambuc * nor may "OpenSSL" appear in their names without prior written 85*ebfedea0SLionel Sambuc * permission of the OpenSSL Project. 86*ebfedea0SLionel Sambuc * 87*ebfedea0SLionel Sambuc * 6. Redistributions of any form whatsoever must retain the following 88*ebfedea0SLionel Sambuc * acknowledgment: 89*ebfedea0SLionel Sambuc * "This product includes software developed by the OpenSSL Project 90*ebfedea0SLionel Sambuc * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 91*ebfedea0SLionel Sambuc * 92*ebfedea0SLionel Sambuc * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 93*ebfedea0SLionel Sambuc * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 94*ebfedea0SLionel Sambuc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 95*ebfedea0SLionel Sambuc * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 96*ebfedea0SLionel Sambuc * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 97*ebfedea0SLionel Sambuc * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 98*ebfedea0SLionel Sambuc * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 99*ebfedea0SLionel Sambuc * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 100*ebfedea0SLionel Sambuc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 101*ebfedea0SLionel Sambuc * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 102*ebfedea0SLionel Sambuc * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 103*ebfedea0SLionel Sambuc * OF THE POSSIBILITY OF SUCH DAMAGE. 104*ebfedea0SLionel Sambuc * ==================================================================== 105*ebfedea0SLionel Sambuc * 106*ebfedea0SLionel Sambuc * This product includes cryptographic software written by Eric Young 107*ebfedea0SLionel Sambuc * (eay@cryptsoft.com). This product includes software written by Tim 108*ebfedea0SLionel Sambuc * Hudson (tjh@cryptsoft.com). 109*ebfedea0SLionel Sambuc * 110*ebfedea0SLionel Sambuc */ 111*ebfedea0SLionel Sambuc 112*ebfedea0SLionel Sambuc #if !defined(_POSIX_C_SOURCE) && defined(OPENSSL_SYS_VMS) 113*ebfedea0SLionel Sambuc #define _POSIX_C_SOURCE 2 /* On VMS, you need to define this to get 114*ebfedea0SLionel Sambuc the declaration of fileno(). The value 115*ebfedea0SLionel Sambuc 2 is to make sure no function defined 116*ebfedea0SLionel Sambuc in POSIX-2 is left undefined. */ 117*ebfedea0SLionel Sambuc #endif 118*ebfedea0SLionel Sambuc #include <stdio.h> 119*ebfedea0SLionel Sambuc #include <stdlib.h> 120*ebfedea0SLionel Sambuc #include <string.h> 121*ebfedea0SLionel Sambuc #if !defined(OPENSSL_SYSNAME_WIN32) && !defined(NETWARE_CLIB) 122*ebfedea0SLionel Sambuc #include <strings.h> 123*ebfedea0SLionel Sambuc #endif 124*ebfedea0SLionel Sambuc #include <sys/types.h> 125*ebfedea0SLionel Sambuc #include <ctype.h> 126*ebfedea0SLionel Sambuc #include <errno.h> 127*ebfedea0SLionel Sambuc #include <assert.h> 128*ebfedea0SLionel Sambuc #include <openssl/err.h> 129*ebfedea0SLionel Sambuc #include <openssl/x509.h> 130*ebfedea0SLionel Sambuc #include <openssl/x509v3.h> 131*ebfedea0SLionel Sambuc #include <openssl/pem.h> 132*ebfedea0SLionel Sambuc #include <openssl/pkcs12.h> 133*ebfedea0SLionel Sambuc #include <openssl/ui.h> 134*ebfedea0SLionel Sambuc #include <openssl/safestack.h> 135*ebfedea0SLionel Sambuc #ifndef OPENSSL_NO_ENGINE 136*ebfedea0SLionel Sambuc #include <openssl/engine.h> 137*ebfedea0SLionel Sambuc #endif 138*ebfedea0SLionel Sambuc #ifndef OPENSSL_NO_RSA 139*ebfedea0SLionel Sambuc #include <openssl/rsa.h> 140*ebfedea0SLionel Sambuc #endif 141*ebfedea0SLionel Sambuc #include <openssl/bn.h> 142*ebfedea0SLionel Sambuc #ifndef OPENSSL_NO_JPAKE 143*ebfedea0SLionel Sambuc #include <openssl/jpake.h> 144*ebfedea0SLionel Sambuc #endif 145*ebfedea0SLionel Sambuc 146*ebfedea0SLionel Sambuc #define NON_MAIN 147*ebfedea0SLionel Sambuc #include "apps.h" 148*ebfedea0SLionel Sambuc #undef NON_MAIN 149*ebfedea0SLionel Sambuc 150*ebfedea0SLionel Sambuc #ifdef _WIN32 151*ebfedea0SLionel Sambuc static int WIN32_rename(const char *from, const char *to); 152*ebfedea0SLionel Sambuc #define rename(from,to) WIN32_rename((from),(to)) 153*ebfedea0SLionel Sambuc #endif 154*ebfedea0SLionel Sambuc 155*ebfedea0SLionel Sambuc typedef struct { 156*ebfedea0SLionel Sambuc const char *name; 157*ebfedea0SLionel Sambuc unsigned long flag; 158*ebfedea0SLionel Sambuc unsigned long mask; 159*ebfedea0SLionel Sambuc } NAME_EX_TBL; 160*ebfedea0SLionel Sambuc 161*ebfedea0SLionel Sambuc static UI_METHOD *ui_method = NULL; 162*ebfedea0SLionel Sambuc 163*ebfedea0SLionel Sambuc static int set_table_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl); 164*ebfedea0SLionel Sambuc static int set_multi_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl); 165*ebfedea0SLionel Sambuc 166*ebfedea0SLionel Sambuc #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA) 167*ebfedea0SLionel Sambuc /* Looks like this stuff is worth moving into separate function */ 168*ebfedea0SLionel Sambuc static EVP_PKEY * 169*ebfedea0SLionel Sambuc load_netscape_key(BIO *err, BIO *key, const char *file, 170*ebfedea0SLionel Sambuc const char *key_descrip, int format); 171*ebfedea0SLionel Sambuc #endif 172*ebfedea0SLionel Sambuc 173*ebfedea0SLionel Sambuc int app_init(long mesgwin); 174*ebfedea0SLionel Sambuc #ifdef undef /* never finished - probably never will be :-) */ 175*ebfedea0SLionel Sambuc int args_from_file(char *file, int *argc, char **argv[]) 176*ebfedea0SLionel Sambuc { 177*ebfedea0SLionel Sambuc FILE *fp; 178*ebfedea0SLionel Sambuc int num,i; 179*ebfedea0SLionel Sambuc unsigned int len; 180*ebfedea0SLionel Sambuc static char *buf=NULL; 181*ebfedea0SLionel Sambuc static char **arg=NULL; 182*ebfedea0SLionel Sambuc char *p; 183*ebfedea0SLionel Sambuc 184*ebfedea0SLionel Sambuc fp=fopen(file,"r"); 185*ebfedea0SLionel Sambuc if (fp == NULL) 186*ebfedea0SLionel Sambuc return(0); 187*ebfedea0SLionel Sambuc 188*ebfedea0SLionel Sambuc if (fseek(fp,0,SEEK_END)==0) 189*ebfedea0SLionel Sambuc len=ftell(fp), rewind(fp); 190*ebfedea0SLionel Sambuc else len=-1; 191*ebfedea0SLionel Sambuc if (len<=0) 192*ebfedea0SLionel Sambuc { 193*ebfedea0SLionel Sambuc fclose(fp); 194*ebfedea0SLionel Sambuc return(0); 195*ebfedea0SLionel Sambuc } 196*ebfedea0SLionel Sambuc 197*ebfedea0SLionel Sambuc *argc=0; 198*ebfedea0SLionel Sambuc *argv=NULL; 199*ebfedea0SLionel Sambuc 200*ebfedea0SLionel Sambuc if (buf != NULL) OPENSSL_free(buf); 201*ebfedea0SLionel Sambuc buf=(char *)OPENSSL_malloc(len+1); 202*ebfedea0SLionel Sambuc if (buf == NULL) return(0); 203*ebfedea0SLionel Sambuc 204*ebfedea0SLionel Sambuc len=fread(buf,1,len,fp); 205*ebfedea0SLionel Sambuc if (len <= 1) return(0); 206*ebfedea0SLionel Sambuc buf[len]='\0'; 207*ebfedea0SLionel Sambuc 208*ebfedea0SLionel Sambuc i=0; 209*ebfedea0SLionel Sambuc for (p=buf; *p; p++) 210*ebfedea0SLionel Sambuc if (*p == '\n') i++; 211*ebfedea0SLionel Sambuc if (arg != NULL) OPENSSL_free(arg); 212*ebfedea0SLionel Sambuc arg=(char **)OPENSSL_malloc(sizeof(char *)*(i*2)); 213*ebfedea0SLionel Sambuc 214*ebfedea0SLionel Sambuc *argv=arg; 215*ebfedea0SLionel Sambuc num=0; 216*ebfedea0SLionel Sambuc p=buf; 217*ebfedea0SLionel Sambuc for (;;) 218*ebfedea0SLionel Sambuc { 219*ebfedea0SLionel Sambuc if (!*p) break; 220*ebfedea0SLionel Sambuc if (*p == '#') /* comment line */ 221*ebfedea0SLionel Sambuc { 222*ebfedea0SLionel Sambuc while (*p && (*p != '\n')) p++; 223*ebfedea0SLionel Sambuc continue; 224*ebfedea0SLionel Sambuc } 225*ebfedea0SLionel Sambuc /* else we have a line */ 226*ebfedea0SLionel Sambuc *(arg++)=p; 227*ebfedea0SLionel Sambuc num++; 228*ebfedea0SLionel Sambuc while (*p && ((*p != ' ') && (*p != '\t') && (*p != '\n'))) 229*ebfedea0SLionel Sambuc p++; 230*ebfedea0SLionel Sambuc if (!*p) break; 231*ebfedea0SLionel Sambuc if (*p == '\n') 232*ebfedea0SLionel Sambuc { 233*ebfedea0SLionel Sambuc *(p++)='\0'; 234*ebfedea0SLionel Sambuc continue; 235*ebfedea0SLionel Sambuc } 236*ebfedea0SLionel Sambuc /* else it is a tab or space */ 237*ebfedea0SLionel Sambuc p++; 238*ebfedea0SLionel Sambuc while (*p && ((*p == ' ') || (*p == '\t') || (*p == '\n'))) 239*ebfedea0SLionel Sambuc p++; 240*ebfedea0SLionel Sambuc if (!*p) break; 241*ebfedea0SLionel Sambuc if (*p == '\n') 242*ebfedea0SLionel Sambuc { 243*ebfedea0SLionel Sambuc p++; 244*ebfedea0SLionel Sambuc continue; 245*ebfedea0SLionel Sambuc } 246*ebfedea0SLionel Sambuc *(arg++)=p++; 247*ebfedea0SLionel Sambuc num++; 248*ebfedea0SLionel Sambuc while (*p && (*p != '\n')) p++; 249*ebfedea0SLionel Sambuc if (!*p) break; 250*ebfedea0SLionel Sambuc /* else *p == '\n' */ 251*ebfedea0SLionel Sambuc *(p++)='\0'; 252*ebfedea0SLionel Sambuc } 253*ebfedea0SLionel Sambuc *argc=num; 254*ebfedea0SLionel Sambuc return(1); 255*ebfedea0SLionel Sambuc } 256*ebfedea0SLionel Sambuc #endif 257*ebfedea0SLionel Sambuc 258*ebfedea0SLionel Sambuc int str2fmt(char *s) 259*ebfedea0SLionel Sambuc { 260*ebfedea0SLionel Sambuc if (s == NULL) 261*ebfedea0SLionel Sambuc return FORMAT_UNDEF; 262*ebfedea0SLionel Sambuc if ((*s == 'D') || (*s == 'd')) 263*ebfedea0SLionel Sambuc return(FORMAT_ASN1); 264*ebfedea0SLionel Sambuc else if ((*s == 'T') || (*s == 't')) 265*ebfedea0SLionel Sambuc return(FORMAT_TEXT); 266*ebfedea0SLionel Sambuc else if ((*s == 'N') || (*s == 'n')) 267*ebfedea0SLionel Sambuc return(FORMAT_NETSCAPE); 268*ebfedea0SLionel Sambuc else if ((*s == 'S') || (*s == 's')) 269*ebfedea0SLionel Sambuc return(FORMAT_SMIME); 270*ebfedea0SLionel Sambuc else if ((*s == 'M') || (*s == 'm')) 271*ebfedea0SLionel Sambuc return(FORMAT_MSBLOB); 272*ebfedea0SLionel Sambuc else if ((*s == '1') 273*ebfedea0SLionel Sambuc || (strcmp(s,"PKCS12") == 0) || (strcmp(s,"pkcs12") == 0) 274*ebfedea0SLionel Sambuc || (strcmp(s,"P12") == 0) || (strcmp(s,"p12") == 0)) 275*ebfedea0SLionel Sambuc return(FORMAT_PKCS12); 276*ebfedea0SLionel Sambuc else if ((*s == 'E') || (*s == 'e')) 277*ebfedea0SLionel Sambuc return(FORMAT_ENGINE); 278*ebfedea0SLionel Sambuc else if ((*s == 'P') || (*s == 'p')) 279*ebfedea0SLionel Sambuc { 280*ebfedea0SLionel Sambuc if (s[1] == 'V' || s[1] == 'v') 281*ebfedea0SLionel Sambuc return FORMAT_PVK; 282*ebfedea0SLionel Sambuc else 283*ebfedea0SLionel Sambuc return(FORMAT_PEM); 284*ebfedea0SLionel Sambuc } 285*ebfedea0SLionel Sambuc else 286*ebfedea0SLionel Sambuc return(FORMAT_UNDEF); 287*ebfedea0SLionel Sambuc } 288*ebfedea0SLionel Sambuc 289*ebfedea0SLionel Sambuc #if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16) || defined(OPENSSL_SYS_NETWARE) 290*ebfedea0SLionel Sambuc void program_name(char *in, char *out, int size) 291*ebfedea0SLionel Sambuc { 292*ebfedea0SLionel Sambuc int i,n; 293*ebfedea0SLionel Sambuc char *p=NULL; 294*ebfedea0SLionel Sambuc 295*ebfedea0SLionel Sambuc n=strlen(in); 296*ebfedea0SLionel Sambuc /* find the last '/', '\' or ':' */ 297*ebfedea0SLionel Sambuc for (i=n-1; i>0; i--) 298*ebfedea0SLionel Sambuc { 299*ebfedea0SLionel Sambuc if ((in[i] == '/') || (in[i] == '\\') || (in[i] == ':')) 300*ebfedea0SLionel Sambuc { 301*ebfedea0SLionel Sambuc p= &(in[i+1]); 302*ebfedea0SLionel Sambuc break; 303*ebfedea0SLionel Sambuc } 304*ebfedea0SLionel Sambuc } 305*ebfedea0SLionel Sambuc if (p == NULL) 306*ebfedea0SLionel Sambuc p=in; 307*ebfedea0SLionel Sambuc n=strlen(p); 308*ebfedea0SLionel Sambuc 309*ebfedea0SLionel Sambuc #if defined(OPENSSL_SYS_NETWARE) 310*ebfedea0SLionel Sambuc /* strip off trailing .nlm if present. */ 311*ebfedea0SLionel Sambuc if ((n > 4) && (p[n-4] == '.') && 312*ebfedea0SLionel Sambuc ((p[n-3] == 'n') || (p[n-3] == 'N')) && 313*ebfedea0SLionel Sambuc ((p[n-2] == 'l') || (p[n-2] == 'L')) && 314*ebfedea0SLionel Sambuc ((p[n-1] == 'm') || (p[n-1] == 'M'))) 315*ebfedea0SLionel Sambuc n-=4; 316*ebfedea0SLionel Sambuc #else 317*ebfedea0SLionel Sambuc /* strip off trailing .exe if present. */ 318*ebfedea0SLionel Sambuc if ((n > 4) && (p[n-4] == '.') && 319*ebfedea0SLionel Sambuc ((p[n-3] == 'e') || (p[n-3] == 'E')) && 320*ebfedea0SLionel Sambuc ((p[n-2] == 'x') || (p[n-2] == 'X')) && 321*ebfedea0SLionel Sambuc ((p[n-1] == 'e') || (p[n-1] == 'E'))) 322*ebfedea0SLionel Sambuc n-=4; 323*ebfedea0SLionel Sambuc #endif 324*ebfedea0SLionel Sambuc 325*ebfedea0SLionel Sambuc if (n > size-1) 326*ebfedea0SLionel Sambuc n=size-1; 327*ebfedea0SLionel Sambuc 328*ebfedea0SLionel Sambuc for (i=0; i<n; i++) 329*ebfedea0SLionel Sambuc { 330*ebfedea0SLionel Sambuc if ((p[i] >= 'A') && (p[i] <= 'Z')) 331*ebfedea0SLionel Sambuc out[i]=p[i]-'A'+'a'; 332*ebfedea0SLionel Sambuc else 333*ebfedea0SLionel Sambuc out[i]=p[i]; 334*ebfedea0SLionel Sambuc } 335*ebfedea0SLionel Sambuc out[n]='\0'; 336*ebfedea0SLionel Sambuc } 337*ebfedea0SLionel Sambuc #else 338*ebfedea0SLionel Sambuc #ifdef OPENSSL_SYS_VMS 339*ebfedea0SLionel Sambuc void program_name(char *in, char *out, int size) 340*ebfedea0SLionel Sambuc { 341*ebfedea0SLionel Sambuc char *p=in, *q; 342*ebfedea0SLionel Sambuc char *chars=":]>"; 343*ebfedea0SLionel Sambuc 344*ebfedea0SLionel Sambuc while(*chars != '\0') 345*ebfedea0SLionel Sambuc { 346*ebfedea0SLionel Sambuc q=strrchr(p,*chars); 347*ebfedea0SLionel Sambuc if (q > p) 348*ebfedea0SLionel Sambuc p = q + 1; 349*ebfedea0SLionel Sambuc chars++; 350*ebfedea0SLionel Sambuc } 351*ebfedea0SLionel Sambuc 352*ebfedea0SLionel Sambuc q=strrchr(p,'.'); 353*ebfedea0SLionel Sambuc if (q == NULL) 354*ebfedea0SLionel Sambuc q = p + strlen(p); 355*ebfedea0SLionel Sambuc strncpy(out,p,size-1); 356*ebfedea0SLionel Sambuc if (q-p >= size) 357*ebfedea0SLionel Sambuc { 358*ebfedea0SLionel Sambuc out[size-1]='\0'; 359*ebfedea0SLionel Sambuc } 360*ebfedea0SLionel Sambuc else 361*ebfedea0SLionel Sambuc { 362*ebfedea0SLionel Sambuc out[q-p]='\0'; 363*ebfedea0SLionel Sambuc } 364*ebfedea0SLionel Sambuc } 365*ebfedea0SLionel Sambuc #else 366*ebfedea0SLionel Sambuc void program_name(char *in, char *out, int size) 367*ebfedea0SLionel Sambuc { 368*ebfedea0SLionel Sambuc char *p; 369*ebfedea0SLionel Sambuc 370*ebfedea0SLionel Sambuc p=strrchr(in,'/'); 371*ebfedea0SLionel Sambuc if (p != NULL) 372*ebfedea0SLionel Sambuc p++; 373*ebfedea0SLionel Sambuc else 374*ebfedea0SLionel Sambuc p=in; 375*ebfedea0SLionel Sambuc BUF_strlcpy(out,p,size); 376*ebfedea0SLionel Sambuc } 377*ebfedea0SLionel Sambuc #endif 378*ebfedea0SLionel Sambuc #endif 379*ebfedea0SLionel Sambuc 380*ebfedea0SLionel Sambuc int chopup_args(ARGS *arg, char *buf, int *argc, char **argv[]) 381*ebfedea0SLionel Sambuc { 382*ebfedea0SLionel Sambuc int num,i; 383*ebfedea0SLionel Sambuc char *p; 384*ebfedea0SLionel Sambuc 385*ebfedea0SLionel Sambuc *argc=0; 386*ebfedea0SLionel Sambuc *argv=NULL; 387*ebfedea0SLionel Sambuc 388*ebfedea0SLionel Sambuc i=0; 389*ebfedea0SLionel Sambuc if (arg->count == 0) 390*ebfedea0SLionel Sambuc { 391*ebfedea0SLionel Sambuc arg->count=20; 392*ebfedea0SLionel Sambuc arg->data=(char **)OPENSSL_malloc(sizeof(char *)*arg->count); 393*ebfedea0SLionel Sambuc } 394*ebfedea0SLionel Sambuc for (i=0; i<arg->count; i++) 395*ebfedea0SLionel Sambuc arg->data[i]=NULL; 396*ebfedea0SLionel Sambuc 397*ebfedea0SLionel Sambuc num=0; 398*ebfedea0SLionel Sambuc p=buf; 399*ebfedea0SLionel Sambuc for (;;) 400*ebfedea0SLionel Sambuc { 401*ebfedea0SLionel Sambuc /* first scan over white space */ 402*ebfedea0SLionel Sambuc if (!*p) break; 403*ebfedea0SLionel Sambuc while (*p && ((*p == ' ') || (*p == '\t') || (*p == '\n'))) 404*ebfedea0SLionel Sambuc p++; 405*ebfedea0SLionel Sambuc if (!*p) break; 406*ebfedea0SLionel Sambuc 407*ebfedea0SLionel Sambuc /* The start of something good :-) */ 408*ebfedea0SLionel Sambuc if (num >= arg->count) 409*ebfedea0SLionel Sambuc { 410*ebfedea0SLionel Sambuc char **tmp_p; 411*ebfedea0SLionel Sambuc int tlen = arg->count + 20; 412*ebfedea0SLionel Sambuc tmp_p = (char **)OPENSSL_realloc(arg->data, 413*ebfedea0SLionel Sambuc sizeof(char *)*tlen); 414*ebfedea0SLionel Sambuc if (tmp_p == NULL) 415*ebfedea0SLionel Sambuc return 0; 416*ebfedea0SLionel Sambuc arg->data = tmp_p; 417*ebfedea0SLionel Sambuc arg->count = tlen; 418*ebfedea0SLionel Sambuc /* initialize newly allocated data */ 419*ebfedea0SLionel Sambuc for (i = num; i < arg->count; i++) 420*ebfedea0SLionel Sambuc arg->data[i] = NULL; 421*ebfedea0SLionel Sambuc } 422*ebfedea0SLionel Sambuc arg->data[num++]=p; 423*ebfedea0SLionel Sambuc 424*ebfedea0SLionel Sambuc /* now look for the end of this */ 425*ebfedea0SLionel Sambuc if ((*p == '\'') || (*p == '\"')) /* scan for closing quote */ 426*ebfedea0SLionel Sambuc { 427*ebfedea0SLionel Sambuc i= *(p++); 428*ebfedea0SLionel Sambuc arg->data[num-1]++; /* jump over quote */ 429*ebfedea0SLionel Sambuc while (*p && (*p != i)) 430*ebfedea0SLionel Sambuc p++; 431*ebfedea0SLionel Sambuc *p='\0'; 432*ebfedea0SLionel Sambuc } 433*ebfedea0SLionel Sambuc else 434*ebfedea0SLionel Sambuc { 435*ebfedea0SLionel Sambuc while (*p && ((*p != ' ') && 436*ebfedea0SLionel Sambuc (*p != '\t') && (*p != '\n'))) 437*ebfedea0SLionel Sambuc p++; 438*ebfedea0SLionel Sambuc 439*ebfedea0SLionel Sambuc if (*p == '\0') 440*ebfedea0SLionel Sambuc p--; 441*ebfedea0SLionel Sambuc else 442*ebfedea0SLionel Sambuc *p='\0'; 443*ebfedea0SLionel Sambuc } 444*ebfedea0SLionel Sambuc p++; 445*ebfedea0SLionel Sambuc } 446*ebfedea0SLionel Sambuc *argc=num; 447*ebfedea0SLionel Sambuc *argv=arg->data; 448*ebfedea0SLionel Sambuc return(1); 449*ebfedea0SLionel Sambuc } 450*ebfedea0SLionel Sambuc 451*ebfedea0SLionel Sambuc #ifndef APP_INIT 452*ebfedea0SLionel Sambuc int app_init(long mesgwin) 453*ebfedea0SLionel Sambuc { 454*ebfedea0SLionel Sambuc return(1); 455*ebfedea0SLionel Sambuc } 456*ebfedea0SLionel Sambuc #endif 457*ebfedea0SLionel Sambuc 458*ebfedea0SLionel Sambuc 459*ebfedea0SLionel Sambuc int dump_cert_text (BIO *out, X509 *x) 460*ebfedea0SLionel Sambuc { 461*ebfedea0SLionel Sambuc char *p; 462*ebfedea0SLionel Sambuc 463*ebfedea0SLionel Sambuc p=X509_NAME_oneline(X509_get_subject_name(x),NULL,0); 464*ebfedea0SLionel Sambuc BIO_puts(out,"subject="); 465*ebfedea0SLionel Sambuc BIO_puts(out,p); 466*ebfedea0SLionel Sambuc OPENSSL_free(p); 467*ebfedea0SLionel Sambuc 468*ebfedea0SLionel Sambuc p=X509_NAME_oneline(X509_get_issuer_name(x),NULL,0); 469*ebfedea0SLionel Sambuc BIO_puts(out,"\nissuer="); 470*ebfedea0SLionel Sambuc BIO_puts(out,p); 471*ebfedea0SLionel Sambuc BIO_puts(out,"\n"); 472*ebfedea0SLionel Sambuc OPENSSL_free(p); 473*ebfedea0SLionel Sambuc 474*ebfedea0SLionel Sambuc return 0; 475*ebfedea0SLionel Sambuc } 476*ebfedea0SLionel Sambuc 477*ebfedea0SLionel Sambuc static int ui_open(UI *ui) 478*ebfedea0SLionel Sambuc { 479*ebfedea0SLionel Sambuc return UI_method_get_opener(UI_OpenSSL())(ui); 480*ebfedea0SLionel Sambuc } 481*ebfedea0SLionel Sambuc static int ui_read(UI *ui, UI_STRING *uis) 482*ebfedea0SLionel Sambuc { 483*ebfedea0SLionel Sambuc if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD 484*ebfedea0SLionel Sambuc && UI_get0_user_data(ui)) 485*ebfedea0SLionel Sambuc { 486*ebfedea0SLionel Sambuc switch(UI_get_string_type(uis)) 487*ebfedea0SLionel Sambuc { 488*ebfedea0SLionel Sambuc case UIT_PROMPT: 489*ebfedea0SLionel Sambuc case UIT_VERIFY: 490*ebfedea0SLionel Sambuc { 491*ebfedea0SLionel Sambuc const char *password = 492*ebfedea0SLionel Sambuc ((PW_CB_DATA *)UI_get0_user_data(ui))->password; 493*ebfedea0SLionel Sambuc if (password && password[0] != '\0') 494*ebfedea0SLionel Sambuc { 495*ebfedea0SLionel Sambuc UI_set_result(ui, uis, password); 496*ebfedea0SLionel Sambuc return 1; 497*ebfedea0SLionel Sambuc } 498*ebfedea0SLionel Sambuc } 499*ebfedea0SLionel Sambuc default: 500*ebfedea0SLionel Sambuc break; 501*ebfedea0SLionel Sambuc } 502*ebfedea0SLionel Sambuc } 503*ebfedea0SLionel Sambuc return UI_method_get_reader(UI_OpenSSL())(ui, uis); 504*ebfedea0SLionel Sambuc } 505*ebfedea0SLionel Sambuc static int ui_write(UI *ui, UI_STRING *uis) 506*ebfedea0SLionel Sambuc { 507*ebfedea0SLionel Sambuc if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD 508*ebfedea0SLionel Sambuc && UI_get0_user_data(ui)) 509*ebfedea0SLionel Sambuc { 510*ebfedea0SLionel Sambuc switch(UI_get_string_type(uis)) 511*ebfedea0SLionel Sambuc { 512*ebfedea0SLionel Sambuc case UIT_PROMPT: 513*ebfedea0SLionel Sambuc case UIT_VERIFY: 514*ebfedea0SLionel Sambuc { 515*ebfedea0SLionel Sambuc const char *password = 516*ebfedea0SLionel Sambuc ((PW_CB_DATA *)UI_get0_user_data(ui))->password; 517*ebfedea0SLionel Sambuc if (password && password[0] != '\0') 518*ebfedea0SLionel Sambuc return 1; 519*ebfedea0SLionel Sambuc } 520*ebfedea0SLionel Sambuc default: 521*ebfedea0SLionel Sambuc break; 522*ebfedea0SLionel Sambuc } 523*ebfedea0SLionel Sambuc } 524*ebfedea0SLionel Sambuc return UI_method_get_writer(UI_OpenSSL())(ui, uis); 525*ebfedea0SLionel Sambuc } 526*ebfedea0SLionel Sambuc static int ui_close(UI *ui) 527*ebfedea0SLionel Sambuc { 528*ebfedea0SLionel Sambuc return UI_method_get_closer(UI_OpenSSL())(ui); 529*ebfedea0SLionel Sambuc } 530*ebfedea0SLionel Sambuc int setup_ui_method(void) 531*ebfedea0SLionel Sambuc { 532*ebfedea0SLionel Sambuc ui_method = UI_create_method("OpenSSL application user interface"); 533*ebfedea0SLionel Sambuc UI_method_set_opener(ui_method, ui_open); 534*ebfedea0SLionel Sambuc UI_method_set_reader(ui_method, ui_read); 535*ebfedea0SLionel Sambuc UI_method_set_writer(ui_method, ui_write); 536*ebfedea0SLionel Sambuc UI_method_set_closer(ui_method, ui_close); 537*ebfedea0SLionel Sambuc return 0; 538*ebfedea0SLionel Sambuc } 539*ebfedea0SLionel Sambuc void destroy_ui_method(void) 540*ebfedea0SLionel Sambuc { 541*ebfedea0SLionel Sambuc if(ui_method) 542*ebfedea0SLionel Sambuc { 543*ebfedea0SLionel Sambuc UI_destroy_method(ui_method); 544*ebfedea0SLionel Sambuc ui_method = NULL; 545*ebfedea0SLionel Sambuc } 546*ebfedea0SLionel Sambuc } 547*ebfedea0SLionel Sambuc int password_callback(char *buf, int bufsiz, int verify, 548*ebfedea0SLionel Sambuc PW_CB_DATA *cb_tmp) 549*ebfedea0SLionel Sambuc { 550*ebfedea0SLionel Sambuc UI *ui = NULL; 551*ebfedea0SLionel Sambuc int res = 0; 552*ebfedea0SLionel Sambuc const char *prompt_info = NULL; 553*ebfedea0SLionel Sambuc const char *password = NULL; 554*ebfedea0SLionel Sambuc PW_CB_DATA *cb_data = (PW_CB_DATA *)cb_tmp; 555*ebfedea0SLionel Sambuc 556*ebfedea0SLionel Sambuc if (cb_data) 557*ebfedea0SLionel Sambuc { 558*ebfedea0SLionel Sambuc if (cb_data->password) 559*ebfedea0SLionel Sambuc password = cb_data->password; 560*ebfedea0SLionel Sambuc if (cb_data->prompt_info) 561*ebfedea0SLionel Sambuc prompt_info = cb_data->prompt_info; 562*ebfedea0SLionel Sambuc } 563*ebfedea0SLionel Sambuc 564*ebfedea0SLionel Sambuc if (password) 565*ebfedea0SLionel Sambuc { 566*ebfedea0SLionel Sambuc res = strlen(password); 567*ebfedea0SLionel Sambuc if (res > bufsiz) 568*ebfedea0SLionel Sambuc res = bufsiz; 569*ebfedea0SLionel Sambuc memcpy(buf, password, res); 570*ebfedea0SLionel Sambuc return res; 571*ebfedea0SLionel Sambuc } 572*ebfedea0SLionel Sambuc 573*ebfedea0SLionel Sambuc ui = UI_new_method(ui_method); 574*ebfedea0SLionel Sambuc if (ui) 575*ebfedea0SLionel Sambuc { 576*ebfedea0SLionel Sambuc int ok = 0; 577*ebfedea0SLionel Sambuc char *buff = NULL; 578*ebfedea0SLionel Sambuc int ui_flags = 0; 579*ebfedea0SLionel Sambuc char *prompt = NULL; 580*ebfedea0SLionel Sambuc 581*ebfedea0SLionel Sambuc prompt = UI_construct_prompt(ui, "pass phrase", 582*ebfedea0SLionel Sambuc prompt_info); 583*ebfedea0SLionel Sambuc 584*ebfedea0SLionel Sambuc ui_flags |= UI_INPUT_FLAG_DEFAULT_PWD; 585*ebfedea0SLionel Sambuc UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0); 586*ebfedea0SLionel Sambuc 587*ebfedea0SLionel Sambuc if (ok >= 0) 588*ebfedea0SLionel Sambuc ok = UI_add_input_string(ui,prompt,ui_flags,buf, 589*ebfedea0SLionel Sambuc PW_MIN_LENGTH,BUFSIZ-1); 590*ebfedea0SLionel Sambuc if (ok >= 0 && verify) 591*ebfedea0SLionel Sambuc { 592*ebfedea0SLionel Sambuc buff = (char *)OPENSSL_malloc(bufsiz); 593*ebfedea0SLionel Sambuc ok = UI_add_verify_string(ui,prompt,ui_flags,buff, 594*ebfedea0SLionel Sambuc PW_MIN_LENGTH,BUFSIZ-1, buf); 595*ebfedea0SLionel Sambuc } 596*ebfedea0SLionel Sambuc if (ok >= 0) 597*ebfedea0SLionel Sambuc do 598*ebfedea0SLionel Sambuc { 599*ebfedea0SLionel Sambuc ok = UI_process(ui); 600*ebfedea0SLionel Sambuc } 601*ebfedea0SLionel Sambuc while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0)); 602*ebfedea0SLionel Sambuc 603*ebfedea0SLionel Sambuc if (buff) 604*ebfedea0SLionel Sambuc { 605*ebfedea0SLionel Sambuc OPENSSL_cleanse(buff,(unsigned int)bufsiz); 606*ebfedea0SLionel Sambuc OPENSSL_free(buff); 607*ebfedea0SLionel Sambuc } 608*ebfedea0SLionel Sambuc 609*ebfedea0SLionel Sambuc if (ok >= 0) 610*ebfedea0SLionel Sambuc res = strlen(buf); 611*ebfedea0SLionel Sambuc if (ok == -1) 612*ebfedea0SLionel Sambuc { 613*ebfedea0SLionel Sambuc BIO_printf(bio_err, "User interface error\n"); 614*ebfedea0SLionel Sambuc ERR_print_errors(bio_err); 615*ebfedea0SLionel Sambuc OPENSSL_cleanse(buf,(unsigned int)bufsiz); 616*ebfedea0SLionel Sambuc res = 0; 617*ebfedea0SLionel Sambuc } 618*ebfedea0SLionel Sambuc if (ok == -2) 619*ebfedea0SLionel Sambuc { 620*ebfedea0SLionel Sambuc BIO_printf(bio_err,"aborted!\n"); 621*ebfedea0SLionel Sambuc OPENSSL_cleanse(buf,(unsigned int)bufsiz); 622*ebfedea0SLionel Sambuc res = 0; 623*ebfedea0SLionel Sambuc } 624*ebfedea0SLionel Sambuc UI_free(ui); 625*ebfedea0SLionel Sambuc OPENSSL_free(prompt); 626*ebfedea0SLionel Sambuc } 627*ebfedea0SLionel Sambuc return res; 628*ebfedea0SLionel Sambuc } 629*ebfedea0SLionel Sambuc 630*ebfedea0SLionel Sambuc static char *app_get_pass(BIO *err, char *arg, int keepbio); 631*ebfedea0SLionel Sambuc 632*ebfedea0SLionel Sambuc int app_passwd(BIO *err, char *arg1, char *arg2, char **pass1, char **pass2) 633*ebfedea0SLionel Sambuc { 634*ebfedea0SLionel Sambuc int same; 635*ebfedea0SLionel Sambuc if(!arg2 || !arg1 || strcmp(arg1, arg2)) same = 0; 636*ebfedea0SLionel Sambuc else same = 1; 637*ebfedea0SLionel Sambuc if(arg1) { 638*ebfedea0SLionel Sambuc *pass1 = app_get_pass(err, arg1, same); 639*ebfedea0SLionel Sambuc if(!*pass1) return 0; 640*ebfedea0SLionel Sambuc } else if(pass1) *pass1 = NULL; 641*ebfedea0SLionel Sambuc if(arg2) { 642*ebfedea0SLionel Sambuc *pass2 = app_get_pass(err, arg2, same ? 2 : 0); 643*ebfedea0SLionel Sambuc if(!*pass2) return 0; 644*ebfedea0SLionel Sambuc } else if(pass2) *pass2 = NULL; 645*ebfedea0SLionel Sambuc return 1; 646*ebfedea0SLionel Sambuc } 647*ebfedea0SLionel Sambuc 648*ebfedea0SLionel Sambuc static char *app_get_pass(BIO *err, char *arg, int keepbio) 649*ebfedea0SLionel Sambuc { 650*ebfedea0SLionel Sambuc char *tmp, tpass[APP_PASS_LEN]; 651*ebfedea0SLionel Sambuc static BIO *pwdbio = NULL; 652*ebfedea0SLionel Sambuc int i; 653*ebfedea0SLionel Sambuc if(!strncmp(arg, "pass:", 5)) return BUF_strdup(arg + 5); 654*ebfedea0SLionel Sambuc if(!strncmp(arg, "env:", 4)) { 655*ebfedea0SLionel Sambuc tmp = getenv(arg + 4); 656*ebfedea0SLionel Sambuc if(!tmp) { 657*ebfedea0SLionel Sambuc BIO_printf(err, "Can't read environment variable %s\n", arg + 4); 658*ebfedea0SLionel Sambuc return NULL; 659*ebfedea0SLionel Sambuc } 660*ebfedea0SLionel Sambuc return BUF_strdup(tmp); 661*ebfedea0SLionel Sambuc } 662*ebfedea0SLionel Sambuc if(!keepbio || !pwdbio) { 663*ebfedea0SLionel Sambuc if(!strncmp(arg, "file:", 5)) { 664*ebfedea0SLionel Sambuc pwdbio = BIO_new_file(arg + 5, "r"); 665*ebfedea0SLionel Sambuc if(!pwdbio) { 666*ebfedea0SLionel Sambuc BIO_printf(err, "Can't open file %s\n", arg + 5); 667*ebfedea0SLionel Sambuc return NULL; 668*ebfedea0SLionel Sambuc } 669*ebfedea0SLionel Sambuc #if !defined(_WIN32) 670*ebfedea0SLionel Sambuc /* 671*ebfedea0SLionel Sambuc * Under _WIN32, which covers even Win64 and CE, file 672*ebfedea0SLionel Sambuc * descriptors referenced by BIO_s_fd are not inherited 673*ebfedea0SLionel Sambuc * by child process and therefore below is not an option. 674*ebfedea0SLionel Sambuc * It could have been an option if bss_fd.c was operating 675*ebfedea0SLionel Sambuc * on real Windows descriptors, such as those obtained 676*ebfedea0SLionel Sambuc * with CreateFile. 677*ebfedea0SLionel Sambuc */ 678*ebfedea0SLionel Sambuc } else if(!strncmp(arg, "fd:", 3)) { 679*ebfedea0SLionel Sambuc BIO *btmp; 680*ebfedea0SLionel Sambuc i = atoi(arg + 3); 681*ebfedea0SLionel Sambuc if(i >= 0) pwdbio = BIO_new_fd(i, BIO_NOCLOSE); 682*ebfedea0SLionel Sambuc if((i < 0) || !pwdbio) { 683*ebfedea0SLionel Sambuc BIO_printf(err, "Can't access file descriptor %s\n", arg + 3); 684*ebfedea0SLionel Sambuc return NULL; 685*ebfedea0SLionel Sambuc } 686*ebfedea0SLionel Sambuc /* Can't do BIO_gets on an fd BIO so add a buffering BIO */ 687*ebfedea0SLionel Sambuc btmp = BIO_new(BIO_f_buffer()); 688*ebfedea0SLionel Sambuc pwdbio = BIO_push(btmp, pwdbio); 689*ebfedea0SLionel Sambuc #endif 690*ebfedea0SLionel Sambuc } else if(!strcmp(arg, "stdin")) { 691*ebfedea0SLionel Sambuc pwdbio = BIO_new_fp(stdin, BIO_NOCLOSE); 692*ebfedea0SLionel Sambuc if(!pwdbio) { 693*ebfedea0SLionel Sambuc BIO_printf(err, "Can't open BIO for stdin\n"); 694*ebfedea0SLionel Sambuc return NULL; 695*ebfedea0SLionel Sambuc } 696*ebfedea0SLionel Sambuc } else { 697*ebfedea0SLionel Sambuc BIO_printf(err, "Invalid password argument \"%s\"\n", arg); 698*ebfedea0SLionel Sambuc return NULL; 699*ebfedea0SLionel Sambuc } 700*ebfedea0SLionel Sambuc } 701*ebfedea0SLionel Sambuc i = BIO_gets(pwdbio, tpass, APP_PASS_LEN); 702*ebfedea0SLionel Sambuc if(keepbio != 1) { 703*ebfedea0SLionel Sambuc BIO_free_all(pwdbio); 704*ebfedea0SLionel Sambuc pwdbio = NULL; 705*ebfedea0SLionel Sambuc } 706*ebfedea0SLionel Sambuc if(i <= 0) { 707*ebfedea0SLionel Sambuc BIO_printf(err, "Error reading password from BIO\n"); 708*ebfedea0SLionel Sambuc return NULL; 709*ebfedea0SLionel Sambuc } 710*ebfedea0SLionel Sambuc tmp = strchr(tpass, '\n'); 711*ebfedea0SLionel Sambuc if(tmp) *tmp = 0; 712*ebfedea0SLionel Sambuc return BUF_strdup(tpass); 713*ebfedea0SLionel Sambuc } 714*ebfedea0SLionel Sambuc 715*ebfedea0SLionel Sambuc int add_oid_section(BIO *err, CONF *conf) 716*ebfedea0SLionel Sambuc { 717*ebfedea0SLionel Sambuc char *p; 718*ebfedea0SLionel Sambuc STACK_OF(CONF_VALUE) *sktmp; 719*ebfedea0SLionel Sambuc CONF_VALUE *cnf; 720*ebfedea0SLionel Sambuc int i; 721*ebfedea0SLionel Sambuc if(!(p=NCONF_get_string(conf,NULL,"oid_section"))) 722*ebfedea0SLionel Sambuc { 723*ebfedea0SLionel Sambuc ERR_clear_error(); 724*ebfedea0SLionel Sambuc return 1; 725*ebfedea0SLionel Sambuc } 726*ebfedea0SLionel Sambuc if(!(sktmp = NCONF_get_section(conf, p))) { 727*ebfedea0SLionel Sambuc BIO_printf(err, "problem loading oid section %s\n", p); 728*ebfedea0SLionel Sambuc return 0; 729*ebfedea0SLionel Sambuc } 730*ebfedea0SLionel Sambuc for(i = 0; i < sk_CONF_VALUE_num(sktmp); i++) { 731*ebfedea0SLionel Sambuc cnf = sk_CONF_VALUE_value(sktmp, i); 732*ebfedea0SLionel Sambuc if(OBJ_create(cnf->value, cnf->name, cnf->name) == NID_undef) { 733*ebfedea0SLionel Sambuc BIO_printf(err, "problem creating object %s=%s\n", 734*ebfedea0SLionel Sambuc cnf->name, cnf->value); 735*ebfedea0SLionel Sambuc return 0; 736*ebfedea0SLionel Sambuc } 737*ebfedea0SLionel Sambuc } 738*ebfedea0SLionel Sambuc return 1; 739*ebfedea0SLionel Sambuc } 740*ebfedea0SLionel Sambuc 741*ebfedea0SLionel Sambuc static int load_pkcs12(BIO *err, BIO *in, const char *desc, 742*ebfedea0SLionel Sambuc pem_password_cb *pem_cb, void *cb_data, 743*ebfedea0SLionel Sambuc EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca) 744*ebfedea0SLionel Sambuc { 745*ebfedea0SLionel Sambuc const char *pass; 746*ebfedea0SLionel Sambuc char tpass[PEM_BUFSIZE]; 747*ebfedea0SLionel Sambuc int len, ret = 0; 748*ebfedea0SLionel Sambuc PKCS12 *p12; 749*ebfedea0SLionel Sambuc p12 = d2i_PKCS12_bio(in, NULL); 750*ebfedea0SLionel Sambuc if (p12 == NULL) 751*ebfedea0SLionel Sambuc { 752*ebfedea0SLionel Sambuc BIO_printf(err, "Error loading PKCS12 file for %s\n", desc); 753*ebfedea0SLionel Sambuc goto die; 754*ebfedea0SLionel Sambuc } 755*ebfedea0SLionel Sambuc /* See if an empty password will do */ 756*ebfedea0SLionel Sambuc if (PKCS12_verify_mac(p12, "", 0) || PKCS12_verify_mac(p12, NULL, 0)) 757*ebfedea0SLionel Sambuc pass = ""; 758*ebfedea0SLionel Sambuc else 759*ebfedea0SLionel Sambuc { 760*ebfedea0SLionel Sambuc if (!pem_cb) 761*ebfedea0SLionel Sambuc pem_cb = (pem_password_cb *)password_callback; 762*ebfedea0SLionel Sambuc len = pem_cb(tpass, PEM_BUFSIZE, 0, cb_data); 763*ebfedea0SLionel Sambuc if (len < 0) 764*ebfedea0SLionel Sambuc { 765*ebfedea0SLionel Sambuc BIO_printf(err, "Passpharse callback error for %s\n", 766*ebfedea0SLionel Sambuc desc); 767*ebfedea0SLionel Sambuc goto die; 768*ebfedea0SLionel Sambuc } 769*ebfedea0SLionel Sambuc if (len < PEM_BUFSIZE) 770*ebfedea0SLionel Sambuc tpass[len] = 0; 771*ebfedea0SLionel Sambuc if (!PKCS12_verify_mac(p12, tpass, len)) 772*ebfedea0SLionel Sambuc { 773*ebfedea0SLionel Sambuc BIO_printf(err, 774*ebfedea0SLionel Sambuc "Mac verify error (wrong password?) in PKCS12 file for %s\n", desc); 775*ebfedea0SLionel Sambuc goto die; 776*ebfedea0SLionel Sambuc } 777*ebfedea0SLionel Sambuc pass = tpass; 778*ebfedea0SLionel Sambuc } 779*ebfedea0SLionel Sambuc ret = PKCS12_parse(p12, pass, pkey, cert, ca); 780*ebfedea0SLionel Sambuc die: 781*ebfedea0SLionel Sambuc if (p12) 782*ebfedea0SLionel Sambuc PKCS12_free(p12); 783*ebfedea0SLionel Sambuc return ret; 784*ebfedea0SLionel Sambuc } 785*ebfedea0SLionel Sambuc 786*ebfedea0SLionel Sambuc X509 *load_cert(BIO *err, const char *file, int format, 787*ebfedea0SLionel Sambuc const char *pass, ENGINE *e, const char *cert_descrip) 788*ebfedea0SLionel Sambuc { 789*ebfedea0SLionel Sambuc X509 *x=NULL; 790*ebfedea0SLionel Sambuc BIO *cert; 791*ebfedea0SLionel Sambuc 792*ebfedea0SLionel Sambuc if ((cert=BIO_new(BIO_s_file())) == NULL) 793*ebfedea0SLionel Sambuc { 794*ebfedea0SLionel Sambuc ERR_print_errors(err); 795*ebfedea0SLionel Sambuc goto end; 796*ebfedea0SLionel Sambuc } 797*ebfedea0SLionel Sambuc 798*ebfedea0SLionel Sambuc if (file == NULL) 799*ebfedea0SLionel Sambuc { 800*ebfedea0SLionel Sambuc #ifdef _IONBF 801*ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_SETVBUF_IONBF 802*ebfedea0SLionel Sambuc setvbuf(stdin, NULL, _IONBF, 0); 803*ebfedea0SLionel Sambuc # endif /* ndef OPENSSL_NO_SETVBUF_IONBF */ 804*ebfedea0SLionel Sambuc #endif 805*ebfedea0SLionel Sambuc BIO_set_fp(cert,stdin,BIO_NOCLOSE); 806*ebfedea0SLionel Sambuc } 807*ebfedea0SLionel Sambuc else 808*ebfedea0SLionel Sambuc { 809*ebfedea0SLionel Sambuc if (BIO_read_filename(cert,file) <= 0) 810*ebfedea0SLionel Sambuc { 811*ebfedea0SLionel Sambuc BIO_printf(err, "Error opening %s %s\n", 812*ebfedea0SLionel Sambuc cert_descrip, file); 813*ebfedea0SLionel Sambuc ERR_print_errors(err); 814*ebfedea0SLionel Sambuc goto end; 815*ebfedea0SLionel Sambuc } 816*ebfedea0SLionel Sambuc } 817*ebfedea0SLionel Sambuc 818*ebfedea0SLionel Sambuc if (format == FORMAT_ASN1) 819*ebfedea0SLionel Sambuc x=d2i_X509_bio(cert,NULL); 820*ebfedea0SLionel Sambuc else if (format == FORMAT_NETSCAPE) 821*ebfedea0SLionel Sambuc { 822*ebfedea0SLionel Sambuc NETSCAPE_X509 *nx; 823*ebfedea0SLionel Sambuc nx=ASN1_item_d2i_bio(ASN1_ITEM_rptr(NETSCAPE_X509),cert,NULL); 824*ebfedea0SLionel Sambuc if (nx == NULL) 825*ebfedea0SLionel Sambuc goto end; 826*ebfedea0SLionel Sambuc 827*ebfedea0SLionel Sambuc if ((strncmp(NETSCAPE_CERT_HDR,(char *)nx->header->data, 828*ebfedea0SLionel Sambuc nx->header->length) != 0)) 829*ebfedea0SLionel Sambuc { 830*ebfedea0SLionel Sambuc NETSCAPE_X509_free(nx); 831*ebfedea0SLionel Sambuc BIO_printf(err,"Error reading header on certificate\n"); 832*ebfedea0SLionel Sambuc goto end; 833*ebfedea0SLionel Sambuc } 834*ebfedea0SLionel Sambuc x=nx->cert; 835*ebfedea0SLionel Sambuc nx->cert = NULL; 836*ebfedea0SLionel Sambuc NETSCAPE_X509_free(nx); 837*ebfedea0SLionel Sambuc } 838*ebfedea0SLionel Sambuc else if (format == FORMAT_PEM) 839*ebfedea0SLionel Sambuc x=PEM_read_bio_X509_AUX(cert,NULL, 840*ebfedea0SLionel Sambuc (pem_password_cb *)password_callback, NULL); 841*ebfedea0SLionel Sambuc else if (format == FORMAT_PKCS12) 842*ebfedea0SLionel Sambuc { 843*ebfedea0SLionel Sambuc if (!load_pkcs12(err, cert,cert_descrip, NULL, NULL, 844*ebfedea0SLionel Sambuc NULL, &x, NULL)) 845*ebfedea0SLionel Sambuc goto end; 846*ebfedea0SLionel Sambuc } 847*ebfedea0SLionel Sambuc else { 848*ebfedea0SLionel Sambuc BIO_printf(err,"bad input format specified for %s\n", 849*ebfedea0SLionel Sambuc cert_descrip); 850*ebfedea0SLionel Sambuc goto end; 851*ebfedea0SLionel Sambuc } 852*ebfedea0SLionel Sambuc end: 853*ebfedea0SLionel Sambuc if (x == NULL) 854*ebfedea0SLionel Sambuc { 855*ebfedea0SLionel Sambuc BIO_printf(err,"unable to load certificate\n"); 856*ebfedea0SLionel Sambuc ERR_print_errors(err); 857*ebfedea0SLionel Sambuc } 858*ebfedea0SLionel Sambuc if (cert != NULL) BIO_free(cert); 859*ebfedea0SLionel Sambuc return(x); 860*ebfedea0SLionel Sambuc } 861*ebfedea0SLionel Sambuc 862*ebfedea0SLionel Sambuc EVP_PKEY *load_key(BIO *err, const char *file, int format, int maybe_stdin, 863*ebfedea0SLionel Sambuc const char *pass, ENGINE *e, const char *key_descrip) 864*ebfedea0SLionel Sambuc { 865*ebfedea0SLionel Sambuc BIO *key=NULL; 866*ebfedea0SLionel Sambuc EVP_PKEY *pkey=NULL; 867*ebfedea0SLionel Sambuc PW_CB_DATA cb_data; 868*ebfedea0SLionel Sambuc 869*ebfedea0SLionel Sambuc cb_data.password = pass; 870*ebfedea0SLionel Sambuc cb_data.prompt_info = file; 871*ebfedea0SLionel Sambuc 872*ebfedea0SLionel Sambuc if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE)) 873*ebfedea0SLionel Sambuc { 874*ebfedea0SLionel Sambuc BIO_printf(err,"no keyfile specified\n"); 875*ebfedea0SLionel Sambuc goto end; 876*ebfedea0SLionel Sambuc } 877*ebfedea0SLionel Sambuc #ifndef OPENSSL_NO_ENGINE 878*ebfedea0SLionel Sambuc if (format == FORMAT_ENGINE) 879*ebfedea0SLionel Sambuc { 880*ebfedea0SLionel Sambuc if (!e) 881*ebfedea0SLionel Sambuc BIO_printf(err,"no engine specified\n"); 882*ebfedea0SLionel Sambuc else 883*ebfedea0SLionel Sambuc { 884*ebfedea0SLionel Sambuc pkey = ENGINE_load_private_key(e, file, 885*ebfedea0SLionel Sambuc ui_method, &cb_data); 886*ebfedea0SLionel Sambuc if (!pkey) 887*ebfedea0SLionel Sambuc { 888*ebfedea0SLionel Sambuc BIO_printf(err,"cannot load %s from engine\n",key_descrip); 889*ebfedea0SLionel Sambuc ERR_print_errors(err); 890*ebfedea0SLionel Sambuc } 891*ebfedea0SLionel Sambuc } 892*ebfedea0SLionel Sambuc goto end; 893*ebfedea0SLionel Sambuc } 894*ebfedea0SLionel Sambuc #endif 895*ebfedea0SLionel Sambuc key=BIO_new(BIO_s_file()); 896*ebfedea0SLionel Sambuc if (key == NULL) 897*ebfedea0SLionel Sambuc { 898*ebfedea0SLionel Sambuc ERR_print_errors(err); 899*ebfedea0SLionel Sambuc goto end; 900*ebfedea0SLionel Sambuc } 901*ebfedea0SLionel Sambuc if (file == NULL && maybe_stdin) 902*ebfedea0SLionel Sambuc { 903*ebfedea0SLionel Sambuc #ifdef _IONBF 904*ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_SETVBUF_IONBF 905*ebfedea0SLionel Sambuc setvbuf(stdin, NULL, _IONBF, 0); 906*ebfedea0SLionel Sambuc # endif /* ndef OPENSSL_NO_SETVBUF_IONBF */ 907*ebfedea0SLionel Sambuc #endif 908*ebfedea0SLionel Sambuc BIO_set_fp(key,stdin,BIO_NOCLOSE); 909*ebfedea0SLionel Sambuc } 910*ebfedea0SLionel Sambuc else 911*ebfedea0SLionel Sambuc if (BIO_read_filename(key,file) <= 0) 912*ebfedea0SLionel Sambuc { 913*ebfedea0SLionel Sambuc BIO_printf(err, "Error opening %s %s\n", 914*ebfedea0SLionel Sambuc key_descrip, file); 915*ebfedea0SLionel Sambuc ERR_print_errors(err); 916*ebfedea0SLionel Sambuc goto end; 917*ebfedea0SLionel Sambuc } 918*ebfedea0SLionel Sambuc if (format == FORMAT_ASN1) 919*ebfedea0SLionel Sambuc { 920*ebfedea0SLionel Sambuc pkey=d2i_PrivateKey_bio(key, NULL); 921*ebfedea0SLionel Sambuc } 922*ebfedea0SLionel Sambuc else if (format == FORMAT_PEM) 923*ebfedea0SLionel Sambuc { 924*ebfedea0SLionel Sambuc pkey=PEM_read_bio_PrivateKey(key,NULL, 925*ebfedea0SLionel Sambuc (pem_password_cb *)password_callback, &cb_data); 926*ebfedea0SLionel Sambuc } 927*ebfedea0SLionel Sambuc #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA) 928*ebfedea0SLionel Sambuc else if (format == FORMAT_NETSCAPE || format == FORMAT_IISSGC) 929*ebfedea0SLionel Sambuc pkey = load_netscape_key(err, key, file, key_descrip, format); 930*ebfedea0SLionel Sambuc #endif 931*ebfedea0SLionel Sambuc else if (format == FORMAT_PKCS12) 932*ebfedea0SLionel Sambuc { 933*ebfedea0SLionel Sambuc if (!load_pkcs12(err, key, key_descrip, 934*ebfedea0SLionel Sambuc (pem_password_cb *)password_callback, &cb_data, 935*ebfedea0SLionel Sambuc &pkey, NULL, NULL)) 936*ebfedea0SLionel Sambuc goto end; 937*ebfedea0SLionel Sambuc } 938*ebfedea0SLionel Sambuc #if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA) && !defined (OPENSSL_NO_RC4) 939*ebfedea0SLionel Sambuc else if (format == FORMAT_MSBLOB) 940*ebfedea0SLionel Sambuc pkey = b2i_PrivateKey_bio(key); 941*ebfedea0SLionel Sambuc else if (format == FORMAT_PVK) 942*ebfedea0SLionel Sambuc pkey = b2i_PVK_bio(key, (pem_password_cb *)password_callback, 943*ebfedea0SLionel Sambuc &cb_data); 944*ebfedea0SLionel Sambuc #endif 945*ebfedea0SLionel Sambuc else 946*ebfedea0SLionel Sambuc { 947*ebfedea0SLionel Sambuc BIO_printf(err,"bad input format specified for key file\n"); 948*ebfedea0SLionel Sambuc goto end; 949*ebfedea0SLionel Sambuc } 950*ebfedea0SLionel Sambuc end: 951*ebfedea0SLionel Sambuc if (key != NULL) BIO_free(key); 952*ebfedea0SLionel Sambuc if (pkey == NULL) 953*ebfedea0SLionel Sambuc { 954*ebfedea0SLionel Sambuc BIO_printf(err,"unable to load %s\n", key_descrip); 955*ebfedea0SLionel Sambuc ERR_print_errors(err); 956*ebfedea0SLionel Sambuc } 957*ebfedea0SLionel Sambuc return(pkey); 958*ebfedea0SLionel Sambuc } 959*ebfedea0SLionel Sambuc 960*ebfedea0SLionel Sambuc EVP_PKEY *load_pubkey(BIO *err, const char *file, int format, int maybe_stdin, 961*ebfedea0SLionel Sambuc const char *pass, ENGINE *e, const char *key_descrip) 962*ebfedea0SLionel Sambuc { 963*ebfedea0SLionel Sambuc BIO *key=NULL; 964*ebfedea0SLionel Sambuc EVP_PKEY *pkey=NULL; 965*ebfedea0SLionel Sambuc PW_CB_DATA cb_data; 966*ebfedea0SLionel Sambuc 967*ebfedea0SLionel Sambuc cb_data.password = pass; 968*ebfedea0SLionel Sambuc cb_data.prompt_info = file; 969*ebfedea0SLionel Sambuc 970*ebfedea0SLionel Sambuc if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE)) 971*ebfedea0SLionel Sambuc { 972*ebfedea0SLionel Sambuc BIO_printf(err,"no keyfile specified\n"); 973*ebfedea0SLionel Sambuc goto end; 974*ebfedea0SLionel Sambuc } 975*ebfedea0SLionel Sambuc #ifndef OPENSSL_NO_ENGINE 976*ebfedea0SLionel Sambuc if (format == FORMAT_ENGINE) 977*ebfedea0SLionel Sambuc { 978*ebfedea0SLionel Sambuc if (!e) 979*ebfedea0SLionel Sambuc BIO_printf(bio_err,"no engine specified\n"); 980*ebfedea0SLionel Sambuc else 981*ebfedea0SLionel Sambuc pkey = ENGINE_load_public_key(e, file, 982*ebfedea0SLionel Sambuc ui_method, &cb_data); 983*ebfedea0SLionel Sambuc goto end; 984*ebfedea0SLionel Sambuc } 985*ebfedea0SLionel Sambuc #endif 986*ebfedea0SLionel Sambuc key=BIO_new(BIO_s_file()); 987*ebfedea0SLionel Sambuc if (key == NULL) 988*ebfedea0SLionel Sambuc { 989*ebfedea0SLionel Sambuc ERR_print_errors(err); 990*ebfedea0SLionel Sambuc goto end; 991*ebfedea0SLionel Sambuc } 992*ebfedea0SLionel Sambuc if (file == NULL && maybe_stdin) 993*ebfedea0SLionel Sambuc { 994*ebfedea0SLionel Sambuc #ifdef _IONBF 995*ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_SETVBUF_IONBF 996*ebfedea0SLionel Sambuc setvbuf(stdin, NULL, _IONBF, 0); 997*ebfedea0SLionel Sambuc # endif /* ndef OPENSSL_NO_SETVBUF_IONBF */ 998*ebfedea0SLionel Sambuc #endif 999*ebfedea0SLionel Sambuc BIO_set_fp(key,stdin,BIO_NOCLOSE); 1000*ebfedea0SLionel Sambuc } 1001*ebfedea0SLionel Sambuc else 1002*ebfedea0SLionel Sambuc if (BIO_read_filename(key,file) <= 0) 1003*ebfedea0SLionel Sambuc { 1004*ebfedea0SLionel Sambuc BIO_printf(err, "Error opening %s %s\n", 1005*ebfedea0SLionel Sambuc key_descrip, file); 1006*ebfedea0SLionel Sambuc ERR_print_errors(err); 1007*ebfedea0SLionel Sambuc goto end; 1008*ebfedea0SLionel Sambuc } 1009*ebfedea0SLionel Sambuc if (format == FORMAT_ASN1) 1010*ebfedea0SLionel Sambuc { 1011*ebfedea0SLionel Sambuc pkey=d2i_PUBKEY_bio(key, NULL); 1012*ebfedea0SLionel Sambuc } 1013*ebfedea0SLionel Sambuc #ifndef OPENSSL_NO_RSA 1014*ebfedea0SLionel Sambuc else if (format == FORMAT_ASN1RSA) 1015*ebfedea0SLionel Sambuc { 1016*ebfedea0SLionel Sambuc RSA *rsa; 1017*ebfedea0SLionel Sambuc rsa = d2i_RSAPublicKey_bio(key, NULL); 1018*ebfedea0SLionel Sambuc if (rsa) 1019*ebfedea0SLionel Sambuc { 1020*ebfedea0SLionel Sambuc pkey = EVP_PKEY_new(); 1021*ebfedea0SLionel Sambuc if (pkey) 1022*ebfedea0SLionel Sambuc EVP_PKEY_set1_RSA(pkey, rsa); 1023*ebfedea0SLionel Sambuc RSA_free(rsa); 1024*ebfedea0SLionel Sambuc } 1025*ebfedea0SLionel Sambuc else 1026*ebfedea0SLionel Sambuc pkey = NULL; 1027*ebfedea0SLionel Sambuc } 1028*ebfedea0SLionel Sambuc else if (format == FORMAT_PEMRSA) 1029*ebfedea0SLionel Sambuc { 1030*ebfedea0SLionel Sambuc RSA *rsa; 1031*ebfedea0SLionel Sambuc rsa = PEM_read_bio_RSAPublicKey(key, NULL, 1032*ebfedea0SLionel Sambuc (pem_password_cb *)password_callback, &cb_data); 1033*ebfedea0SLionel Sambuc if (rsa) 1034*ebfedea0SLionel Sambuc { 1035*ebfedea0SLionel Sambuc pkey = EVP_PKEY_new(); 1036*ebfedea0SLionel Sambuc if (pkey) 1037*ebfedea0SLionel Sambuc EVP_PKEY_set1_RSA(pkey, rsa); 1038*ebfedea0SLionel Sambuc RSA_free(rsa); 1039*ebfedea0SLionel Sambuc } 1040*ebfedea0SLionel Sambuc else 1041*ebfedea0SLionel Sambuc pkey = NULL; 1042*ebfedea0SLionel Sambuc } 1043*ebfedea0SLionel Sambuc #endif 1044*ebfedea0SLionel Sambuc else if (format == FORMAT_PEM) 1045*ebfedea0SLionel Sambuc { 1046*ebfedea0SLionel Sambuc pkey=PEM_read_bio_PUBKEY(key,NULL, 1047*ebfedea0SLionel Sambuc (pem_password_cb *)password_callback, &cb_data); 1048*ebfedea0SLionel Sambuc } 1049*ebfedea0SLionel Sambuc #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA) 1050*ebfedea0SLionel Sambuc else if (format == FORMAT_NETSCAPE || format == FORMAT_IISSGC) 1051*ebfedea0SLionel Sambuc pkey = load_netscape_key(err, key, file, key_descrip, format); 1052*ebfedea0SLionel Sambuc #endif 1053*ebfedea0SLionel Sambuc #if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA) 1054*ebfedea0SLionel Sambuc else if (format == FORMAT_MSBLOB) 1055*ebfedea0SLionel Sambuc pkey = b2i_PublicKey_bio(key); 1056*ebfedea0SLionel Sambuc #endif 1057*ebfedea0SLionel Sambuc else 1058*ebfedea0SLionel Sambuc { 1059*ebfedea0SLionel Sambuc BIO_printf(err,"bad input format specified for key file\n"); 1060*ebfedea0SLionel Sambuc goto end; 1061*ebfedea0SLionel Sambuc } 1062*ebfedea0SLionel Sambuc end: 1063*ebfedea0SLionel Sambuc if (key != NULL) BIO_free(key); 1064*ebfedea0SLionel Sambuc if (pkey == NULL) 1065*ebfedea0SLionel Sambuc BIO_printf(err,"unable to load %s\n", key_descrip); 1066*ebfedea0SLionel Sambuc return(pkey); 1067*ebfedea0SLionel Sambuc } 1068*ebfedea0SLionel Sambuc 1069*ebfedea0SLionel Sambuc #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA) 1070*ebfedea0SLionel Sambuc static EVP_PKEY * 1071*ebfedea0SLionel Sambuc load_netscape_key(BIO *err, BIO *key, const char *file, 1072*ebfedea0SLionel Sambuc const char *key_descrip, int format) 1073*ebfedea0SLionel Sambuc { 1074*ebfedea0SLionel Sambuc EVP_PKEY *pkey; 1075*ebfedea0SLionel Sambuc BUF_MEM *buf; 1076*ebfedea0SLionel Sambuc RSA *rsa; 1077*ebfedea0SLionel Sambuc const unsigned char *p; 1078*ebfedea0SLionel Sambuc int size, i; 1079*ebfedea0SLionel Sambuc 1080*ebfedea0SLionel Sambuc buf=BUF_MEM_new(); 1081*ebfedea0SLionel Sambuc pkey = EVP_PKEY_new(); 1082*ebfedea0SLionel Sambuc size = 0; 1083*ebfedea0SLionel Sambuc if (buf == NULL || pkey == NULL) 1084*ebfedea0SLionel Sambuc goto error; 1085*ebfedea0SLionel Sambuc for (;;) 1086*ebfedea0SLionel Sambuc { 1087*ebfedea0SLionel Sambuc if (!BUF_MEM_grow_clean(buf,size+1024*10)) 1088*ebfedea0SLionel Sambuc goto error; 1089*ebfedea0SLionel Sambuc i = BIO_read(key, &(buf->data[size]), 1024*10); 1090*ebfedea0SLionel Sambuc size += i; 1091*ebfedea0SLionel Sambuc if (i == 0) 1092*ebfedea0SLionel Sambuc break; 1093*ebfedea0SLionel Sambuc if (i < 0) 1094*ebfedea0SLionel Sambuc { 1095*ebfedea0SLionel Sambuc BIO_printf(err, "Error reading %s %s", 1096*ebfedea0SLionel Sambuc key_descrip, file); 1097*ebfedea0SLionel Sambuc goto error; 1098*ebfedea0SLionel Sambuc } 1099*ebfedea0SLionel Sambuc } 1100*ebfedea0SLionel Sambuc p=(unsigned char *)buf->data; 1101*ebfedea0SLionel Sambuc rsa = d2i_RSA_NET(NULL,&p,(long)size,NULL, 1102*ebfedea0SLionel Sambuc (format == FORMAT_IISSGC ? 1 : 0)); 1103*ebfedea0SLionel Sambuc if (rsa == NULL) 1104*ebfedea0SLionel Sambuc goto error; 1105*ebfedea0SLionel Sambuc BUF_MEM_free(buf); 1106*ebfedea0SLionel Sambuc EVP_PKEY_set1_RSA(pkey, rsa); 1107*ebfedea0SLionel Sambuc return pkey; 1108*ebfedea0SLionel Sambuc error: 1109*ebfedea0SLionel Sambuc BUF_MEM_free(buf); 1110*ebfedea0SLionel Sambuc EVP_PKEY_free(pkey); 1111*ebfedea0SLionel Sambuc return NULL; 1112*ebfedea0SLionel Sambuc } 1113*ebfedea0SLionel Sambuc #endif /* ndef OPENSSL_NO_RC4 */ 1114*ebfedea0SLionel Sambuc 1115*ebfedea0SLionel Sambuc static int load_certs_crls(BIO *err, const char *file, int format, 1116*ebfedea0SLionel Sambuc const char *pass, ENGINE *e, const char *desc, 1117*ebfedea0SLionel Sambuc STACK_OF(X509) **pcerts, STACK_OF(X509_CRL) **pcrls) 1118*ebfedea0SLionel Sambuc { 1119*ebfedea0SLionel Sambuc int i; 1120*ebfedea0SLionel Sambuc BIO *bio; 1121*ebfedea0SLionel Sambuc STACK_OF(X509_INFO) *xis = NULL; 1122*ebfedea0SLionel Sambuc X509_INFO *xi; 1123*ebfedea0SLionel Sambuc PW_CB_DATA cb_data; 1124*ebfedea0SLionel Sambuc int rv = 0; 1125*ebfedea0SLionel Sambuc 1126*ebfedea0SLionel Sambuc cb_data.password = pass; 1127*ebfedea0SLionel Sambuc cb_data.prompt_info = file; 1128*ebfedea0SLionel Sambuc 1129*ebfedea0SLionel Sambuc if (format != FORMAT_PEM) 1130*ebfedea0SLionel Sambuc { 1131*ebfedea0SLionel Sambuc BIO_printf(err,"bad input format specified for %s\n", desc); 1132*ebfedea0SLionel Sambuc return 0; 1133*ebfedea0SLionel Sambuc } 1134*ebfedea0SLionel Sambuc 1135*ebfedea0SLionel Sambuc if (file == NULL) 1136*ebfedea0SLionel Sambuc bio = BIO_new_fp(stdin,BIO_NOCLOSE); 1137*ebfedea0SLionel Sambuc else 1138*ebfedea0SLionel Sambuc bio = BIO_new_file(file, "r"); 1139*ebfedea0SLionel Sambuc 1140*ebfedea0SLionel Sambuc if (bio == NULL) 1141*ebfedea0SLionel Sambuc { 1142*ebfedea0SLionel Sambuc BIO_printf(err, "Error opening %s %s\n", 1143*ebfedea0SLionel Sambuc desc, file ? file : "stdin"); 1144*ebfedea0SLionel Sambuc ERR_print_errors(err); 1145*ebfedea0SLionel Sambuc return 0; 1146*ebfedea0SLionel Sambuc } 1147*ebfedea0SLionel Sambuc 1148*ebfedea0SLionel Sambuc xis = PEM_X509_INFO_read_bio(bio, NULL, 1149*ebfedea0SLionel Sambuc (pem_password_cb *)password_callback, &cb_data); 1150*ebfedea0SLionel Sambuc 1151*ebfedea0SLionel Sambuc BIO_free(bio); 1152*ebfedea0SLionel Sambuc 1153*ebfedea0SLionel Sambuc if (pcerts) 1154*ebfedea0SLionel Sambuc { 1155*ebfedea0SLionel Sambuc *pcerts = sk_X509_new_null(); 1156*ebfedea0SLionel Sambuc if (!*pcerts) 1157*ebfedea0SLionel Sambuc goto end; 1158*ebfedea0SLionel Sambuc } 1159*ebfedea0SLionel Sambuc 1160*ebfedea0SLionel Sambuc if (pcrls) 1161*ebfedea0SLionel Sambuc { 1162*ebfedea0SLionel Sambuc *pcrls = sk_X509_CRL_new_null(); 1163*ebfedea0SLionel Sambuc if (!*pcrls) 1164*ebfedea0SLionel Sambuc goto end; 1165*ebfedea0SLionel Sambuc } 1166*ebfedea0SLionel Sambuc 1167*ebfedea0SLionel Sambuc for(i = 0; i < sk_X509_INFO_num(xis); i++) 1168*ebfedea0SLionel Sambuc { 1169*ebfedea0SLionel Sambuc xi = sk_X509_INFO_value (xis, i); 1170*ebfedea0SLionel Sambuc if (xi->x509 && pcerts) 1171*ebfedea0SLionel Sambuc { 1172*ebfedea0SLionel Sambuc if (!sk_X509_push(*pcerts, xi->x509)) 1173*ebfedea0SLionel Sambuc goto end; 1174*ebfedea0SLionel Sambuc xi->x509 = NULL; 1175*ebfedea0SLionel Sambuc } 1176*ebfedea0SLionel Sambuc if (xi->crl && pcrls) 1177*ebfedea0SLionel Sambuc { 1178*ebfedea0SLionel Sambuc if (!sk_X509_CRL_push(*pcrls, xi->crl)) 1179*ebfedea0SLionel Sambuc goto end; 1180*ebfedea0SLionel Sambuc xi->crl = NULL; 1181*ebfedea0SLionel Sambuc } 1182*ebfedea0SLionel Sambuc } 1183*ebfedea0SLionel Sambuc 1184*ebfedea0SLionel Sambuc if (pcerts && sk_X509_num(*pcerts) > 0) 1185*ebfedea0SLionel Sambuc rv = 1; 1186*ebfedea0SLionel Sambuc 1187*ebfedea0SLionel Sambuc if (pcrls && sk_X509_CRL_num(*pcrls) > 0) 1188*ebfedea0SLionel Sambuc rv = 1; 1189*ebfedea0SLionel Sambuc 1190*ebfedea0SLionel Sambuc end: 1191*ebfedea0SLionel Sambuc 1192*ebfedea0SLionel Sambuc if (xis) 1193*ebfedea0SLionel Sambuc sk_X509_INFO_pop_free(xis, X509_INFO_free); 1194*ebfedea0SLionel Sambuc 1195*ebfedea0SLionel Sambuc if (rv == 0) 1196*ebfedea0SLionel Sambuc { 1197*ebfedea0SLionel Sambuc if (pcerts) 1198*ebfedea0SLionel Sambuc { 1199*ebfedea0SLionel Sambuc sk_X509_pop_free(*pcerts, X509_free); 1200*ebfedea0SLionel Sambuc *pcerts = NULL; 1201*ebfedea0SLionel Sambuc } 1202*ebfedea0SLionel Sambuc if (pcrls) 1203*ebfedea0SLionel Sambuc { 1204*ebfedea0SLionel Sambuc sk_X509_CRL_pop_free(*pcrls, X509_CRL_free); 1205*ebfedea0SLionel Sambuc *pcrls = NULL; 1206*ebfedea0SLionel Sambuc } 1207*ebfedea0SLionel Sambuc BIO_printf(err,"unable to load %s\n", 1208*ebfedea0SLionel Sambuc pcerts ? "certificates" : "CRLs"); 1209*ebfedea0SLionel Sambuc ERR_print_errors(err); 1210*ebfedea0SLionel Sambuc } 1211*ebfedea0SLionel Sambuc return rv; 1212*ebfedea0SLionel Sambuc } 1213*ebfedea0SLionel Sambuc 1214*ebfedea0SLionel Sambuc STACK_OF(X509) *load_certs(BIO *err, const char *file, int format, 1215*ebfedea0SLionel Sambuc const char *pass, ENGINE *e, const char *desc) 1216*ebfedea0SLionel Sambuc { 1217*ebfedea0SLionel Sambuc STACK_OF(X509) *certs; 1218*ebfedea0SLionel Sambuc if (!load_certs_crls(err, file, format, pass, e, desc, &certs, NULL)) 1219*ebfedea0SLionel Sambuc return NULL; 1220*ebfedea0SLionel Sambuc return certs; 1221*ebfedea0SLionel Sambuc } 1222*ebfedea0SLionel Sambuc 1223*ebfedea0SLionel Sambuc STACK_OF(X509_CRL) *load_crls(BIO *err, const char *file, int format, 1224*ebfedea0SLionel Sambuc const char *pass, ENGINE *e, const char *desc) 1225*ebfedea0SLionel Sambuc { 1226*ebfedea0SLionel Sambuc STACK_OF(X509_CRL) *crls; 1227*ebfedea0SLionel Sambuc if (!load_certs_crls(err, file, format, pass, e, desc, NULL, &crls)) 1228*ebfedea0SLionel Sambuc return NULL; 1229*ebfedea0SLionel Sambuc return crls; 1230*ebfedea0SLionel Sambuc } 1231*ebfedea0SLionel Sambuc 1232*ebfedea0SLionel Sambuc #define X509V3_EXT_UNKNOWN_MASK (0xfL << 16) 1233*ebfedea0SLionel Sambuc /* Return error for unknown extensions */ 1234*ebfedea0SLionel Sambuc #define X509V3_EXT_DEFAULT 0 1235*ebfedea0SLionel Sambuc /* Print error for unknown extensions */ 1236*ebfedea0SLionel Sambuc #define X509V3_EXT_ERROR_UNKNOWN (1L << 16) 1237*ebfedea0SLionel Sambuc /* ASN1 parse unknown extensions */ 1238*ebfedea0SLionel Sambuc #define X509V3_EXT_PARSE_UNKNOWN (2L << 16) 1239*ebfedea0SLionel Sambuc /* BIO_dump unknown extensions */ 1240*ebfedea0SLionel Sambuc #define X509V3_EXT_DUMP_UNKNOWN (3L << 16) 1241*ebfedea0SLionel Sambuc 1242*ebfedea0SLionel Sambuc #define X509_FLAG_CA (X509_FLAG_NO_ISSUER | X509_FLAG_NO_PUBKEY | \ 1243*ebfedea0SLionel Sambuc X509_FLAG_NO_HEADER | X509_FLAG_NO_VERSION) 1244*ebfedea0SLionel Sambuc 1245*ebfedea0SLionel Sambuc int set_cert_ex(unsigned long *flags, const char *arg) 1246*ebfedea0SLionel Sambuc { 1247*ebfedea0SLionel Sambuc static const NAME_EX_TBL cert_tbl[] = { 1248*ebfedea0SLionel Sambuc { "compatible", X509_FLAG_COMPAT, 0xffffffffl}, 1249*ebfedea0SLionel Sambuc { "ca_default", X509_FLAG_CA, 0xffffffffl}, 1250*ebfedea0SLionel Sambuc { "no_header", X509_FLAG_NO_HEADER, 0}, 1251*ebfedea0SLionel Sambuc { "no_version", X509_FLAG_NO_VERSION, 0}, 1252*ebfedea0SLionel Sambuc { "no_serial", X509_FLAG_NO_SERIAL, 0}, 1253*ebfedea0SLionel Sambuc { "no_signame", X509_FLAG_NO_SIGNAME, 0}, 1254*ebfedea0SLionel Sambuc { "no_validity", X509_FLAG_NO_VALIDITY, 0}, 1255*ebfedea0SLionel Sambuc { "no_subject", X509_FLAG_NO_SUBJECT, 0}, 1256*ebfedea0SLionel Sambuc { "no_issuer", X509_FLAG_NO_ISSUER, 0}, 1257*ebfedea0SLionel Sambuc { "no_pubkey", X509_FLAG_NO_PUBKEY, 0}, 1258*ebfedea0SLionel Sambuc { "no_extensions", X509_FLAG_NO_EXTENSIONS, 0}, 1259*ebfedea0SLionel Sambuc { "no_sigdump", X509_FLAG_NO_SIGDUMP, 0}, 1260*ebfedea0SLionel Sambuc { "no_aux", X509_FLAG_NO_AUX, 0}, 1261*ebfedea0SLionel Sambuc { "no_attributes", X509_FLAG_NO_ATTRIBUTES, 0}, 1262*ebfedea0SLionel Sambuc { "ext_default", X509V3_EXT_DEFAULT, X509V3_EXT_UNKNOWN_MASK}, 1263*ebfedea0SLionel Sambuc { "ext_error", X509V3_EXT_ERROR_UNKNOWN, X509V3_EXT_UNKNOWN_MASK}, 1264*ebfedea0SLionel Sambuc { "ext_parse", X509V3_EXT_PARSE_UNKNOWN, X509V3_EXT_UNKNOWN_MASK}, 1265*ebfedea0SLionel Sambuc { "ext_dump", X509V3_EXT_DUMP_UNKNOWN, X509V3_EXT_UNKNOWN_MASK}, 1266*ebfedea0SLionel Sambuc { NULL, 0, 0} 1267*ebfedea0SLionel Sambuc }; 1268*ebfedea0SLionel Sambuc return set_multi_opts(flags, arg, cert_tbl); 1269*ebfedea0SLionel Sambuc } 1270*ebfedea0SLionel Sambuc 1271*ebfedea0SLionel Sambuc int set_name_ex(unsigned long *flags, const char *arg) 1272*ebfedea0SLionel Sambuc { 1273*ebfedea0SLionel Sambuc static const NAME_EX_TBL ex_tbl[] = { 1274*ebfedea0SLionel Sambuc { "esc_2253", ASN1_STRFLGS_ESC_2253, 0}, 1275*ebfedea0SLionel Sambuc { "esc_ctrl", ASN1_STRFLGS_ESC_CTRL, 0}, 1276*ebfedea0SLionel Sambuc { "esc_msb", ASN1_STRFLGS_ESC_MSB, 0}, 1277*ebfedea0SLionel Sambuc { "use_quote", ASN1_STRFLGS_ESC_QUOTE, 0}, 1278*ebfedea0SLionel Sambuc { "utf8", ASN1_STRFLGS_UTF8_CONVERT, 0}, 1279*ebfedea0SLionel Sambuc { "ignore_type", ASN1_STRFLGS_IGNORE_TYPE, 0}, 1280*ebfedea0SLionel Sambuc { "show_type", ASN1_STRFLGS_SHOW_TYPE, 0}, 1281*ebfedea0SLionel Sambuc { "dump_all", ASN1_STRFLGS_DUMP_ALL, 0}, 1282*ebfedea0SLionel Sambuc { "dump_nostr", ASN1_STRFLGS_DUMP_UNKNOWN, 0}, 1283*ebfedea0SLionel Sambuc { "dump_der", ASN1_STRFLGS_DUMP_DER, 0}, 1284*ebfedea0SLionel Sambuc { "compat", XN_FLAG_COMPAT, 0xffffffffL}, 1285*ebfedea0SLionel Sambuc { "sep_comma_plus", XN_FLAG_SEP_COMMA_PLUS, XN_FLAG_SEP_MASK}, 1286*ebfedea0SLionel Sambuc { "sep_comma_plus_space", XN_FLAG_SEP_CPLUS_SPC, XN_FLAG_SEP_MASK}, 1287*ebfedea0SLionel Sambuc { "sep_semi_plus_space", XN_FLAG_SEP_SPLUS_SPC, XN_FLAG_SEP_MASK}, 1288*ebfedea0SLionel Sambuc { "sep_multiline", XN_FLAG_SEP_MULTILINE, XN_FLAG_SEP_MASK}, 1289*ebfedea0SLionel Sambuc { "dn_rev", XN_FLAG_DN_REV, 0}, 1290*ebfedea0SLionel Sambuc { "nofname", XN_FLAG_FN_NONE, XN_FLAG_FN_MASK}, 1291*ebfedea0SLionel Sambuc { "sname", XN_FLAG_FN_SN, XN_FLAG_FN_MASK}, 1292*ebfedea0SLionel Sambuc { "lname", XN_FLAG_FN_LN, XN_FLAG_FN_MASK}, 1293*ebfedea0SLionel Sambuc { "align", XN_FLAG_FN_ALIGN, 0}, 1294*ebfedea0SLionel Sambuc { "oid", XN_FLAG_FN_OID, XN_FLAG_FN_MASK}, 1295*ebfedea0SLionel Sambuc { "space_eq", XN_FLAG_SPC_EQ, 0}, 1296*ebfedea0SLionel Sambuc { "dump_unknown", XN_FLAG_DUMP_UNKNOWN_FIELDS, 0}, 1297*ebfedea0SLionel Sambuc { "RFC2253", XN_FLAG_RFC2253, 0xffffffffL}, 1298*ebfedea0SLionel Sambuc { "oneline", XN_FLAG_ONELINE, 0xffffffffL}, 1299*ebfedea0SLionel Sambuc { "multiline", XN_FLAG_MULTILINE, 0xffffffffL}, 1300*ebfedea0SLionel Sambuc { "ca_default", XN_FLAG_MULTILINE, 0xffffffffL}, 1301*ebfedea0SLionel Sambuc { NULL, 0, 0} 1302*ebfedea0SLionel Sambuc }; 1303*ebfedea0SLionel Sambuc return set_multi_opts(flags, arg, ex_tbl); 1304*ebfedea0SLionel Sambuc } 1305*ebfedea0SLionel Sambuc 1306*ebfedea0SLionel Sambuc int set_ext_copy(int *copy_type, const char *arg) 1307*ebfedea0SLionel Sambuc { 1308*ebfedea0SLionel Sambuc if (!strcasecmp(arg, "none")) 1309*ebfedea0SLionel Sambuc *copy_type = EXT_COPY_NONE; 1310*ebfedea0SLionel Sambuc else if (!strcasecmp(arg, "copy")) 1311*ebfedea0SLionel Sambuc *copy_type = EXT_COPY_ADD; 1312*ebfedea0SLionel Sambuc else if (!strcasecmp(arg, "copyall")) 1313*ebfedea0SLionel Sambuc *copy_type = EXT_COPY_ALL; 1314*ebfedea0SLionel Sambuc else 1315*ebfedea0SLionel Sambuc return 0; 1316*ebfedea0SLionel Sambuc return 1; 1317*ebfedea0SLionel Sambuc } 1318*ebfedea0SLionel Sambuc 1319*ebfedea0SLionel Sambuc int copy_extensions(X509 *x, X509_REQ *req, int copy_type) 1320*ebfedea0SLionel Sambuc { 1321*ebfedea0SLionel Sambuc STACK_OF(X509_EXTENSION) *exts = NULL; 1322*ebfedea0SLionel Sambuc X509_EXTENSION *ext, *tmpext; 1323*ebfedea0SLionel Sambuc ASN1_OBJECT *obj; 1324*ebfedea0SLionel Sambuc int i, idx, ret = 0; 1325*ebfedea0SLionel Sambuc if (!x || !req || (copy_type == EXT_COPY_NONE)) 1326*ebfedea0SLionel Sambuc return 1; 1327*ebfedea0SLionel Sambuc exts = X509_REQ_get_extensions(req); 1328*ebfedea0SLionel Sambuc 1329*ebfedea0SLionel Sambuc for(i = 0; i < sk_X509_EXTENSION_num(exts); i++) { 1330*ebfedea0SLionel Sambuc ext = sk_X509_EXTENSION_value(exts, i); 1331*ebfedea0SLionel Sambuc obj = X509_EXTENSION_get_object(ext); 1332*ebfedea0SLionel Sambuc idx = X509_get_ext_by_OBJ(x, obj, -1); 1333*ebfedea0SLionel Sambuc /* Does extension exist? */ 1334*ebfedea0SLionel Sambuc if (idx != -1) { 1335*ebfedea0SLionel Sambuc /* If normal copy don't override existing extension */ 1336*ebfedea0SLionel Sambuc if (copy_type == EXT_COPY_ADD) 1337*ebfedea0SLionel Sambuc continue; 1338*ebfedea0SLionel Sambuc /* Delete all extensions of same type */ 1339*ebfedea0SLionel Sambuc do { 1340*ebfedea0SLionel Sambuc tmpext = X509_get_ext(x, idx); 1341*ebfedea0SLionel Sambuc X509_delete_ext(x, idx); 1342*ebfedea0SLionel Sambuc X509_EXTENSION_free(tmpext); 1343*ebfedea0SLionel Sambuc idx = X509_get_ext_by_OBJ(x, obj, -1); 1344*ebfedea0SLionel Sambuc } while (idx != -1); 1345*ebfedea0SLionel Sambuc } 1346*ebfedea0SLionel Sambuc if (!X509_add_ext(x, ext, -1)) 1347*ebfedea0SLionel Sambuc goto end; 1348*ebfedea0SLionel Sambuc } 1349*ebfedea0SLionel Sambuc 1350*ebfedea0SLionel Sambuc ret = 1; 1351*ebfedea0SLionel Sambuc 1352*ebfedea0SLionel Sambuc end: 1353*ebfedea0SLionel Sambuc 1354*ebfedea0SLionel Sambuc sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); 1355*ebfedea0SLionel Sambuc 1356*ebfedea0SLionel Sambuc return ret; 1357*ebfedea0SLionel Sambuc } 1358*ebfedea0SLionel Sambuc 1359*ebfedea0SLionel Sambuc 1360*ebfedea0SLionel Sambuc 1361*ebfedea0SLionel Sambuc 1362*ebfedea0SLionel Sambuc static int set_multi_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl) 1363*ebfedea0SLionel Sambuc { 1364*ebfedea0SLionel Sambuc STACK_OF(CONF_VALUE) *vals; 1365*ebfedea0SLionel Sambuc CONF_VALUE *val; 1366*ebfedea0SLionel Sambuc int i, ret = 1; 1367*ebfedea0SLionel Sambuc if(!arg) return 0; 1368*ebfedea0SLionel Sambuc vals = X509V3_parse_list(arg); 1369*ebfedea0SLionel Sambuc for (i = 0; i < sk_CONF_VALUE_num(vals); i++) { 1370*ebfedea0SLionel Sambuc val = sk_CONF_VALUE_value(vals, i); 1371*ebfedea0SLionel Sambuc if (!set_table_opts(flags, val->name, in_tbl)) 1372*ebfedea0SLionel Sambuc ret = 0; 1373*ebfedea0SLionel Sambuc } 1374*ebfedea0SLionel Sambuc sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); 1375*ebfedea0SLionel Sambuc return ret; 1376*ebfedea0SLionel Sambuc } 1377*ebfedea0SLionel Sambuc 1378*ebfedea0SLionel Sambuc static int set_table_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl) 1379*ebfedea0SLionel Sambuc { 1380*ebfedea0SLionel Sambuc char c; 1381*ebfedea0SLionel Sambuc const NAME_EX_TBL *ptbl; 1382*ebfedea0SLionel Sambuc c = arg[0]; 1383*ebfedea0SLionel Sambuc 1384*ebfedea0SLionel Sambuc if(c == '-') { 1385*ebfedea0SLionel Sambuc c = 0; 1386*ebfedea0SLionel Sambuc arg++; 1387*ebfedea0SLionel Sambuc } else if (c == '+') { 1388*ebfedea0SLionel Sambuc c = 1; 1389*ebfedea0SLionel Sambuc arg++; 1390*ebfedea0SLionel Sambuc } else c = 1; 1391*ebfedea0SLionel Sambuc 1392*ebfedea0SLionel Sambuc for(ptbl = in_tbl; ptbl->name; ptbl++) { 1393*ebfedea0SLionel Sambuc if(!strcasecmp(arg, ptbl->name)) { 1394*ebfedea0SLionel Sambuc *flags &= ~ptbl->mask; 1395*ebfedea0SLionel Sambuc if(c) *flags |= ptbl->flag; 1396*ebfedea0SLionel Sambuc else *flags &= ~ptbl->flag; 1397*ebfedea0SLionel Sambuc return 1; 1398*ebfedea0SLionel Sambuc } 1399*ebfedea0SLionel Sambuc } 1400*ebfedea0SLionel Sambuc return 0; 1401*ebfedea0SLionel Sambuc } 1402*ebfedea0SLionel Sambuc 1403*ebfedea0SLionel Sambuc void print_name(BIO *out, const char *title, X509_NAME *nm, unsigned long lflags) 1404*ebfedea0SLionel Sambuc { 1405*ebfedea0SLionel Sambuc char *buf; 1406*ebfedea0SLionel Sambuc char mline = 0; 1407*ebfedea0SLionel Sambuc int indent = 0; 1408*ebfedea0SLionel Sambuc 1409*ebfedea0SLionel Sambuc if(title) BIO_puts(out, title); 1410*ebfedea0SLionel Sambuc if((lflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) { 1411*ebfedea0SLionel Sambuc mline = 1; 1412*ebfedea0SLionel Sambuc indent = 4; 1413*ebfedea0SLionel Sambuc } 1414*ebfedea0SLionel Sambuc if(lflags == XN_FLAG_COMPAT) { 1415*ebfedea0SLionel Sambuc buf = X509_NAME_oneline(nm, 0, 0); 1416*ebfedea0SLionel Sambuc BIO_puts(out, buf); 1417*ebfedea0SLionel Sambuc BIO_puts(out, "\n"); 1418*ebfedea0SLionel Sambuc OPENSSL_free(buf); 1419*ebfedea0SLionel Sambuc } else { 1420*ebfedea0SLionel Sambuc if(mline) BIO_puts(out, "\n"); 1421*ebfedea0SLionel Sambuc X509_NAME_print_ex(out, nm, indent, lflags); 1422*ebfedea0SLionel Sambuc BIO_puts(out, "\n"); 1423*ebfedea0SLionel Sambuc } 1424*ebfedea0SLionel Sambuc } 1425*ebfedea0SLionel Sambuc 1426*ebfedea0SLionel Sambuc X509_STORE *setup_verify(BIO *bp, char *CAfile, char *CApath) 1427*ebfedea0SLionel Sambuc { 1428*ebfedea0SLionel Sambuc X509_STORE *store; 1429*ebfedea0SLionel Sambuc X509_LOOKUP *lookup; 1430*ebfedea0SLionel Sambuc if(!(store = X509_STORE_new())) goto end; 1431*ebfedea0SLionel Sambuc lookup=X509_STORE_add_lookup(store,X509_LOOKUP_file()); 1432*ebfedea0SLionel Sambuc if (lookup == NULL) goto end; 1433*ebfedea0SLionel Sambuc if (CAfile) { 1434*ebfedea0SLionel Sambuc if(!X509_LOOKUP_load_file(lookup,CAfile,X509_FILETYPE_PEM)) { 1435*ebfedea0SLionel Sambuc BIO_printf(bp, "Error loading file %s\n", CAfile); 1436*ebfedea0SLionel Sambuc goto end; 1437*ebfedea0SLionel Sambuc } 1438*ebfedea0SLionel Sambuc } else X509_LOOKUP_load_file(lookup,NULL,X509_FILETYPE_DEFAULT); 1439*ebfedea0SLionel Sambuc 1440*ebfedea0SLionel Sambuc lookup=X509_STORE_add_lookup(store,X509_LOOKUP_hash_dir()); 1441*ebfedea0SLionel Sambuc if (lookup == NULL) goto end; 1442*ebfedea0SLionel Sambuc if (CApath) { 1443*ebfedea0SLionel Sambuc if(!X509_LOOKUP_add_dir(lookup,CApath,X509_FILETYPE_PEM)) { 1444*ebfedea0SLionel Sambuc BIO_printf(bp, "Error loading directory %s\n", CApath); 1445*ebfedea0SLionel Sambuc goto end; 1446*ebfedea0SLionel Sambuc } 1447*ebfedea0SLionel Sambuc } else X509_LOOKUP_add_dir(lookup,NULL,X509_FILETYPE_DEFAULT); 1448*ebfedea0SLionel Sambuc 1449*ebfedea0SLionel Sambuc ERR_clear_error(); 1450*ebfedea0SLionel Sambuc return store; 1451*ebfedea0SLionel Sambuc end: 1452*ebfedea0SLionel Sambuc X509_STORE_free(store); 1453*ebfedea0SLionel Sambuc return NULL; 1454*ebfedea0SLionel Sambuc } 1455*ebfedea0SLionel Sambuc 1456*ebfedea0SLionel Sambuc #ifndef OPENSSL_NO_ENGINE 1457*ebfedea0SLionel Sambuc /* Try to load an engine in a shareable library */ 1458*ebfedea0SLionel Sambuc static ENGINE *try_load_engine(BIO *err, const char *engine, int debug) 1459*ebfedea0SLionel Sambuc { 1460*ebfedea0SLionel Sambuc ENGINE *e = ENGINE_by_id("dynamic"); 1461*ebfedea0SLionel Sambuc if (e) 1462*ebfedea0SLionel Sambuc { 1463*ebfedea0SLionel Sambuc if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", engine, 0) 1464*ebfedea0SLionel Sambuc || !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0)) 1465*ebfedea0SLionel Sambuc { 1466*ebfedea0SLionel Sambuc ENGINE_free(e); 1467*ebfedea0SLionel Sambuc e = NULL; 1468*ebfedea0SLionel Sambuc } 1469*ebfedea0SLionel Sambuc } 1470*ebfedea0SLionel Sambuc return e; 1471*ebfedea0SLionel Sambuc } 1472*ebfedea0SLionel Sambuc 1473*ebfedea0SLionel Sambuc ENGINE *setup_engine(BIO *err, const char *engine, int debug) 1474*ebfedea0SLionel Sambuc { 1475*ebfedea0SLionel Sambuc ENGINE *e = NULL; 1476*ebfedea0SLionel Sambuc 1477*ebfedea0SLionel Sambuc if (engine) 1478*ebfedea0SLionel Sambuc { 1479*ebfedea0SLionel Sambuc if(strcmp(engine, "auto") == 0) 1480*ebfedea0SLionel Sambuc { 1481*ebfedea0SLionel Sambuc BIO_printf(err,"enabling auto ENGINE support\n"); 1482*ebfedea0SLionel Sambuc ENGINE_register_all_complete(); 1483*ebfedea0SLionel Sambuc return NULL; 1484*ebfedea0SLionel Sambuc } 1485*ebfedea0SLionel Sambuc if((e = ENGINE_by_id(engine)) == NULL 1486*ebfedea0SLionel Sambuc && (e = try_load_engine(err, engine, debug)) == NULL) 1487*ebfedea0SLionel Sambuc { 1488*ebfedea0SLionel Sambuc BIO_printf(err,"invalid engine \"%s\"\n", engine); 1489*ebfedea0SLionel Sambuc ERR_print_errors(err); 1490*ebfedea0SLionel Sambuc return NULL; 1491*ebfedea0SLionel Sambuc } 1492*ebfedea0SLionel Sambuc if (debug) 1493*ebfedea0SLionel Sambuc { 1494*ebfedea0SLionel Sambuc ENGINE_ctrl(e, ENGINE_CTRL_SET_LOGSTREAM, 1495*ebfedea0SLionel Sambuc 0, err, 0); 1496*ebfedea0SLionel Sambuc } 1497*ebfedea0SLionel Sambuc ENGINE_ctrl_cmd(e, "SET_USER_INTERFACE", 0, ui_method, 0, 1); 1498*ebfedea0SLionel Sambuc if(!ENGINE_set_default(e, ENGINE_METHOD_ALL)) 1499*ebfedea0SLionel Sambuc { 1500*ebfedea0SLionel Sambuc BIO_printf(err,"can't use that engine\n"); 1501*ebfedea0SLionel Sambuc ERR_print_errors(err); 1502*ebfedea0SLionel Sambuc ENGINE_free(e); 1503*ebfedea0SLionel Sambuc return NULL; 1504*ebfedea0SLionel Sambuc } 1505*ebfedea0SLionel Sambuc 1506*ebfedea0SLionel Sambuc BIO_printf(err,"engine \"%s\" set.\n", ENGINE_get_id(e)); 1507*ebfedea0SLionel Sambuc 1508*ebfedea0SLionel Sambuc /* Free our "structural" reference. */ 1509*ebfedea0SLionel Sambuc ENGINE_free(e); 1510*ebfedea0SLionel Sambuc } 1511*ebfedea0SLionel Sambuc return e; 1512*ebfedea0SLionel Sambuc } 1513*ebfedea0SLionel Sambuc #endif 1514*ebfedea0SLionel Sambuc 1515*ebfedea0SLionel Sambuc int load_config(BIO *err, CONF *cnf) 1516*ebfedea0SLionel Sambuc { 1517*ebfedea0SLionel Sambuc static int load_config_called = 0; 1518*ebfedea0SLionel Sambuc if (load_config_called) 1519*ebfedea0SLionel Sambuc return 1; 1520*ebfedea0SLionel Sambuc load_config_called = 1; 1521*ebfedea0SLionel Sambuc if (!cnf) 1522*ebfedea0SLionel Sambuc cnf = config; 1523*ebfedea0SLionel Sambuc if (!cnf) 1524*ebfedea0SLionel Sambuc return 1; 1525*ebfedea0SLionel Sambuc 1526*ebfedea0SLionel Sambuc OPENSSL_load_builtin_modules(); 1527*ebfedea0SLionel Sambuc 1528*ebfedea0SLionel Sambuc if (CONF_modules_load(cnf, NULL, 0) <= 0) 1529*ebfedea0SLionel Sambuc { 1530*ebfedea0SLionel Sambuc BIO_printf(err, "Error configuring OpenSSL\n"); 1531*ebfedea0SLionel Sambuc ERR_print_errors(err); 1532*ebfedea0SLionel Sambuc return 0; 1533*ebfedea0SLionel Sambuc } 1534*ebfedea0SLionel Sambuc return 1; 1535*ebfedea0SLionel Sambuc } 1536*ebfedea0SLionel Sambuc 1537*ebfedea0SLionel Sambuc char *make_config_name() 1538*ebfedea0SLionel Sambuc { 1539*ebfedea0SLionel Sambuc const char *t=X509_get_default_cert_area(); 1540*ebfedea0SLionel Sambuc size_t len; 1541*ebfedea0SLionel Sambuc char *p; 1542*ebfedea0SLionel Sambuc 1543*ebfedea0SLionel Sambuc len=strlen(t)+strlen(OPENSSL_CONF)+2; 1544*ebfedea0SLionel Sambuc p=OPENSSL_malloc(len); 1545*ebfedea0SLionel Sambuc BUF_strlcpy(p,t,len); 1546*ebfedea0SLionel Sambuc #ifndef OPENSSL_SYS_VMS 1547*ebfedea0SLionel Sambuc BUF_strlcat(p,"/",len); 1548*ebfedea0SLionel Sambuc #endif 1549*ebfedea0SLionel Sambuc BUF_strlcat(p,OPENSSL_CONF,len); 1550*ebfedea0SLionel Sambuc 1551*ebfedea0SLionel Sambuc return p; 1552*ebfedea0SLionel Sambuc } 1553*ebfedea0SLionel Sambuc 1554*ebfedea0SLionel Sambuc static unsigned long index_serial_hash(const OPENSSL_CSTRING *a) 1555*ebfedea0SLionel Sambuc { 1556*ebfedea0SLionel Sambuc const char *n; 1557*ebfedea0SLionel Sambuc 1558*ebfedea0SLionel Sambuc n=a[DB_serial]; 1559*ebfedea0SLionel Sambuc while (*n == '0') n++; 1560*ebfedea0SLionel Sambuc return(lh_strhash(n)); 1561*ebfedea0SLionel Sambuc } 1562*ebfedea0SLionel Sambuc 1563*ebfedea0SLionel Sambuc static int index_serial_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b) 1564*ebfedea0SLionel Sambuc { 1565*ebfedea0SLionel Sambuc const char *aa,*bb; 1566*ebfedea0SLionel Sambuc 1567*ebfedea0SLionel Sambuc for (aa=a[DB_serial]; *aa == '0'; aa++); 1568*ebfedea0SLionel Sambuc for (bb=b[DB_serial]; *bb == '0'; bb++); 1569*ebfedea0SLionel Sambuc return(strcmp(aa,bb)); 1570*ebfedea0SLionel Sambuc } 1571*ebfedea0SLionel Sambuc 1572*ebfedea0SLionel Sambuc static int index_name_qual(char **a) 1573*ebfedea0SLionel Sambuc { return(a[0][0] == 'V'); } 1574*ebfedea0SLionel Sambuc 1575*ebfedea0SLionel Sambuc static unsigned long index_name_hash(const OPENSSL_CSTRING *a) 1576*ebfedea0SLionel Sambuc { return(lh_strhash(a[DB_name])); } 1577*ebfedea0SLionel Sambuc 1578*ebfedea0SLionel Sambuc int index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b) 1579*ebfedea0SLionel Sambuc { return(strcmp(a[DB_name], b[DB_name])); } 1580*ebfedea0SLionel Sambuc 1581*ebfedea0SLionel Sambuc static IMPLEMENT_LHASH_HASH_FN(index_serial, OPENSSL_CSTRING) 1582*ebfedea0SLionel Sambuc static IMPLEMENT_LHASH_COMP_FN(index_serial, OPENSSL_CSTRING) 1583*ebfedea0SLionel Sambuc static IMPLEMENT_LHASH_HASH_FN(index_name, OPENSSL_CSTRING) 1584*ebfedea0SLionel Sambuc static IMPLEMENT_LHASH_COMP_FN(index_name, OPENSSL_CSTRING) 1585*ebfedea0SLionel Sambuc 1586*ebfedea0SLionel Sambuc #undef BSIZE 1587*ebfedea0SLionel Sambuc #define BSIZE 256 1588*ebfedea0SLionel Sambuc 1589*ebfedea0SLionel Sambuc BIGNUM *load_serial(char *serialfile, int create, ASN1_INTEGER **retai) 1590*ebfedea0SLionel Sambuc { 1591*ebfedea0SLionel Sambuc BIO *in=NULL; 1592*ebfedea0SLionel Sambuc BIGNUM *ret=NULL; 1593*ebfedea0SLionel Sambuc MS_STATIC char buf[1024]; 1594*ebfedea0SLionel Sambuc ASN1_INTEGER *ai=NULL; 1595*ebfedea0SLionel Sambuc 1596*ebfedea0SLionel Sambuc ai=ASN1_INTEGER_new(); 1597*ebfedea0SLionel Sambuc if (ai == NULL) goto err; 1598*ebfedea0SLionel Sambuc 1599*ebfedea0SLionel Sambuc if ((in=BIO_new(BIO_s_file())) == NULL) 1600*ebfedea0SLionel Sambuc { 1601*ebfedea0SLionel Sambuc ERR_print_errors(bio_err); 1602*ebfedea0SLionel Sambuc goto err; 1603*ebfedea0SLionel Sambuc } 1604*ebfedea0SLionel Sambuc 1605*ebfedea0SLionel Sambuc if (BIO_read_filename(in,serialfile) <= 0) 1606*ebfedea0SLionel Sambuc { 1607*ebfedea0SLionel Sambuc if (!create) 1608*ebfedea0SLionel Sambuc { 1609*ebfedea0SLionel Sambuc perror(serialfile); 1610*ebfedea0SLionel Sambuc goto err; 1611*ebfedea0SLionel Sambuc } 1612*ebfedea0SLionel Sambuc else 1613*ebfedea0SLionel Sambuc { 1614*ebfedea0SLionel Sambuc ret=BN_new(); 1615*ebfedea0SLionel Sambuc if (ret == NULL || !rand_serial(ret, ai)) 1616*ebfedea0SLionel Sambuc BIO_printf(bio_err, "Out of memory\n"); 1617*ebfedea0SLionel Sambuc } 1618*ebfedea0SLionel Sambuc } 1619*ebfedea0SLionel Sambuc else 1620*ebfedea0SLionel Sambuc { 1621*ebfedea0SLionel Sambuc if (!a2i_ASN1_INTEGER(in,ai,buf,1024)) 1622*ebfedea0SLionel Sambuc { 1623*ebfedea0SLionel Sambuc BIO_printf(bio_err,"unable to load number from %s\n", 1624*ebfedea0SLionel Sambuc serialfile); 1625*ebfedea0SLionel Sambuc goto err; 1626*ebfedea0SLionel Sambuc } 1627*ebfedea0SLionel Sambuc ret=ASN1_INTEGER_to_BN(ai,NULL); 1628*ebfedea0SLionel Sambuc if (ret == NULL) 1629*ebfedea0SLionel Sambuc { 1630*ebfedea0SLionel Sambuc BIO_printf(bio_err,"error converting number from bin to BIGNUM\n"); 1631*ebfedea0SLionel Sambuc goto err; 1632*ebfedea0SLionel Sambuc } 1633*ebfedea0SLionel Sambuc } 1634*ebfedea0SLionel Sambuc 1635*ebfedea0SLionel Sambuc if (ret && retai) 1636*ebfedea0SLionel Sambuc { 1637*ebfedea0SLionel Sambuc *retai = ai; 1638*ebfedea0SLionel Sambuc ai = NULL; 1639*ebfedea0SLionel Sambuc } 1640*ebfedea0SLionel Sambuc err: 1641*ebfedea0SLionel Sambuc if (in != NULL) BIO_free(in); 1642*ebfedea0SLionel Sambuc if (ai != NULL) ASN1_INTEGER_free(ai); 1643*ebfedea0SLionel Sambuc return(ret); 1644*ebfedea0SLionel Sambuc } 1645*ebfedea0SLionel Sambuc 1646*ebfedea0SLionel Sambuc int save_serial(char *serialfile, char *suffix, BIGNUM *serial, ASN1_INTEGER **retai) 1647*ebfedea0SLionel Sambuc { 1648*ebfedea0SLionel Sambuc char buf[1][BSIZE]; 1649*ebfedea0SLionel Sambuc BIO *out = NULL; 1650*ebfedea0SLionel Sambuc int ret=0; 1651*ebfedea0SLionel Sambuc ASN1_INTEGER *ai=NULL; 1652*ebfedea0SLionel Sambuc int j; 1653*ebfedea0SLionel Sambuc 1654*ebfedea0SLionel Sambuc if (suffix == NULL) 1655*ebfedea0SLionel Sambuc j = strlen(serialfile); 1656*ebfedea0SLionel Sambuc else 1657*ebfedea0SLionel Sambuc j = strlen(serialfile) + strlen(suffix) + 1; 1658*ebfedea0SLionel Sambuc if (j >= BSIZE) 1659*ebfedea0SLionel Sambuc { 1660*ebfedea0SLionel Sambuc BIO_printf(bio_err,"file name too long\n"); 1661*ebfedea0SLionel Sambuc goto err; 1662*ebfedea0SLionel Sambuc } 1663*ebfedea0SLionel Sambuc 1664*ebfedea0SLionel Sambuc if (suffix == NULL) 1665*ebfedea0SLionel Sambuc BUF_strlcpy(buf[0], serialfile, BSIZE); 1666*ebfedea0SLionel Sambuc else 1667*ebfedea0SLionel Sambuc { 1668*ebfedea0SLionel Sambuc #ifndef OPENSSL_SYS_VMS 1669*ebfedea0SLionel Sambuc j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", serialfile, suffix); 1670*ebfedea0SLionel Sambuc #else 1671*ebfedea0SLionel Sambuc j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", serialfile, suffix); 1672*ebfedea0SLionel Sambuc #endif 1673*ebfedea0SLionel Sambuc } 1674*ebfedea0SLionel Sambuc #ifdef RL_DEBUG 1675*ebfedea0SLionel Sambuc BIO_printf(bio_err, "DEBUG: writing \"%s\"\n", buf[0]); 1676*ebfedea0SLionel Sambuc #endif 1677*ebfedea0SLionel Sambuc out=BIO_new(BIO_s_file()); 1678*ebfedea0SLionel Sambuc if (out == NULL) 1679*ebfedea0SLionel Sambuc { 1680*ebfedea0SLionel Sambuc ERR_print_errors(bio_err); 1681*ebfedea0SLionel Sambuc goto err; 1682*ebfedea0SLionel Sambuc } 1683*ebfedea0SLionel Sambuc if (BIO_write_filename(out,buf[0]) <= 0) 1684*ebfedea0SLionel Sambuc { 1685*ebfedea0SLionel Sambuc perror(serialfile); 1686*ebfedea0SLionel Sambuc goto err; 1687*ebfedea0SLionel Sambuc } 1688*ebfedea0SLionel Sambuc 1689*ebfedea0SLionel Sambuc if ((ai=BN_to_ASN1_INTEGER(serial,NULL)) == NULL) 1690*ebfedea0SLionel Sambuc { 1691*ebfedea0SLionel Sambuc BIO_printf(bio_err,"error converting serial to ASN.1 format\n"); 1692*ebfedea0SLionel Sambuc goto err; 1693*ebfedea0SLionel Sambuc } 1694*ebfedea0SLionel Sambuc i2a_ASN1_INTEGER(out,ai); 1695*ebfedea0SLionel Sambuc BIO_puts(out,"\n"); 1696*ebfedea0SLionel Sambuc ret=1; 1697*ebfedea0SLionel Sambuc if (retai) 1698*ebfedea0SLionel Sambuc { 1699*ebfedea0SLionel Sambuc *retai = ai; 1700*ebfedea0SLionel Sambuc ai = NULL; 1701*ebfedea0SLionel Sambuc } 1702*ebfedea0SLionel Sambuc err: 1703*ebfedea0SLionel Sambuc if (out != NULL) BIO_free_all(out); 1704*ebfedea0SLionel Sambuc if (ai != NULL) ASN1_INTEGER_free(ai); 1705*ebfedea0SLionel Sambuc return(ret); 1706*ebfedea0SLionel Sambuc } 1707*ebfedea0SLionel Sambuc 1708*ebfedea0SLionel Sambuc int rotate_serial(char *serialfile, char *new_suffix, char *old_suffix) 1709*ebfedea0SLionel Sambuc { 1710*ebfedea0SLionel Sambuc char buf[5][BSIZE]; 1711*ebfedea0SLionel Sambuc int i,j; 1712*ebfedea0SLionel Sambuc 1713*ebfedea0SLionel Sambuc i = strlen(serialfile) + strlen(old_suffix); 1714*ebfedea0SLionel Sambuc j = strlen(serialfile) + strlen(new_suffix); 1715*ebfedea0SLionel Sambuc if (i > j) j = i; 1716*ebfedea0SLionel Sambuc if (j + 1 >= BSIZE) 1717*ebfedea0SLionel Sambuc { 1718*ebfedea0SLionel Sambuc BIO_printf(bio_err,"file name too long\n"); 1719*ebfedea0SLionel Sambuc goto err; 1720*ebfedea0SLionel Sambuc } 1721*ebfedea0SLionel Sambuc 1722*ebfedea0SLionel Sambuc #ifndef OPENSSL_SYS_VMS 1723*ebfedea0SLionel Sambuc j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", 1724*ebfedea0SLionel Sambuc serialfile, new_suffix); 1725*ebfedea0SLionel Sambuc #else 1726*ebfedea0SLionel Sambuc j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", 1727*ebfedea0SLionel Sambuc serialfile, new_suffix); 1728*ebfedea0SLionel Sambuc #endif 1729*ebfedea0SLionel Sambuc #ifndef OPENSSL_SYS_VMS 1730*ebfedea0SLionel Sambuc j = BIO_snprintf(buf[1], sizeof buf[1], "%s.%s", 1731*ebfedea0SLionel Sambuc serialfile, old_suffix); 1732*ebfedea0SLionel Sambuc #else 1733*ebfedea0SLionel Sambuc j = BIO_snprintf(buf[1], sizeof buf[1], "%s-%s", 1734*ebfedea0SLionel Sambuc serialfile, old_suffix); 1735*ebfedea0SLionel Sambuc #endif 1736*ebfedea0SLionel Sambuc #ifdef RL_DEBUG 1737*ebfedea0SLionel Sambuc BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", 1738*ebfedea0SLionel Sambuc serialfile, buf[1]); 1739*ebfedea0SLionel Sambuc #endif 1740*ebfedea0SLionel Sambuc if (rename(serialfile,buf[1]) < 0 && errno != ENOENT 1741*ebfedea0SLionel Sambuc #ifdef ENOTDIR 1742*ebfedea0SLionel Sambuc && errno != ENOTDIR 1743*ebfedea0SLionel Sambuc #endif 1744*ebfedea0SLionel Sambuc ) { 1745*ebfedea0SLionel Sambuc BIO_printf(bio_err, 1746*ebfedea0SLionel Sambuc "unable to rename %s to %s\n", 1747*ebfedea0SLionel Sambuc serialfile, buf[1]); 1748*ebfedea0SLionel Sambuc perror("reason"); 1749*ebfedea0SLionel Sambuc goto err; 1750*ebfedea0SLionel Sambuc } 1751*ebfedea0SLionel Sambuc #ifdef RL_DEBUG 1752*ebfedea0SLionel Sambuc BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", 1753*ebfedea0SLionel Sambuc buf[0],serialfile); 1754*ebfedea0SLionel Sambuc #endif 1755*ebfedea0SLionel Sambuc if (rename(buf[0],serialfile) < 0) 1756*ebfedea0SLionel Sambuc { 1757*ebfedea0SLionel Sambuc BIO_printf(bio_err, 1758*ebfedea0SLionel Sambuc "unable to rename %s to %s\n", 1759*ebfedea0SLionel Sambuc buf[0],serialfile); 1760*ebfedea0SLionel Sambuc perror("reason"); 1761*ebfedea0SLionel Sambuc rename(buf[1],serialfile); 1762*ebfedea0SLionel Sambuc goto err; 1763*ebfedea0SLionel Sambuc } 1764*ebfedea0SLionel Sambuc return 1; 1765*ebfedea0SLionel Sambuc err: 1766*ebfedea0SLionel Sambuc return 0; 1767*ebfedea0SLionel Sambuc } 1768*ebfedea0SLionel Sambuc 1769*ebfedea0SLionel Sambuc int rand_serial(BIGNUM *b, ASN1_INTEGER *ai) 1770*ebfedea0SLionel Sambuc { 1771*ebfedea0SLionel Sambuc BIGNUM *btmp; 1772*ebfedea0SLionel Sambuc int ret = 0; 1773*ebfedea0SLionel Sambuc if (b) 1774*ebfedea0SLionel Sambuc btmp = b; 1775*ebfedea0SLionel Sambuc else 1776*ebfedea0SLionel Sambuc btmp = BN_new(); 1777*ebfedea0SLionel Sambuc 1778*ebfedea0SLionel Sambuc if (!btmp) 1779*ebfedea0SLionel Sambuc return 0; 1780*ebfedea0SLionel Sambuc 1781*ebfedea0SLionel Sambuc if (!BN_pseudo_rand(btmp, SERIAL_RAND_BITS, 0, 0)) 1782*ebfedea0SLionel Sambuc goto error; 1783*ebfedea0SLionel Sambuc if (ai && !BN_to_ASN1_INTEGER(btmp, ai)) 1784*ebfedea0SLionel Sambuc goto error; 1785*ebfedea0SLionel Sambuc 1786*ebfedea0SLionel Sambuc ret = 1; 1787*ebfedea0SLionel Sambuc 1788*ebfedea0SLionel Sambuc error: 1789*ebfedea0SLionel Sambuc 1790*ebfedea0SLionel Sambuc if (!b) 1791*ebfedea0SLionel Sambuc BN_free(btmp); 1792*ebfedea0SLionel Sambuc 1793*ebfedea0SLionel Sambuc return ret; 1794*ebfedea0SLionel Sambuc } 1795*ebfedea0SLionel Sambuc 1796*ebfedea0SLionel Sambuc CA_DB *load_index(char *dbfile, DB_ATTR *db_attr) 1797*ebfedea0SLionel Sambuc { 1798*ebfedea0SLionel Sambuc CA_DB *retdb = NULL; 1799*ebfedea0SLionel Sambuc TXT_DB *tmpdb = NULL; 1800*ebfedea0SLionel Sambuc BIO *in = BIO_new(BIO_s_file()); 1801*ebfedea0SLionel Sambuc CONF *dbattr_conf = NULL; 1802*ebfedea0SLionel Sambuc char buf[1][BSIZE]; 1803*ebfedea0SLionel Sambuc long errorline= -1; 1804*ebfedea0SLionel Sambuc 1805*ebfedea0SLionel Sambuc if (in == NULL) 1806*ebfedea0SLionel Sambuc { 1807*ebfedea0SLionel Sambuc ERR_print_errors(bio_err); 1808*ebfedea0SLionel Sambuc goto err; 1809*ebfedea0SLionel Sambuc } 1810*ebfedea0SLionel Sambuc if (BIO_read_filename(in,dbfile) <= 0) 1811*ebfedea0SLionel Sambuc { 1812*ebfedea0SLionel Sambuc perror(dbfile); 1813*ebfedea0SLionel Sambuc BIO_printf(bio_err,"unable to open '%s'\n",dbfile); 1814*ebfedea0SLionel Sambuc goto err; 1815*ebfedea0SLionel Sambuc } 1816*ebfedea0SLionel Sambuc if ((tmpdb = TXT_DB_read(in,DB_NUMBER)) == NULL) 1817*ebfedea0SLionel Sambuc goto err; 1818*ebfedea0SLionel Sambuc 1819*ebfedea0SLionel Sambuc #ifndef OPENSSL_SYS_VMS 1820*ebfedea0SLionel Sambuc BIO_snprintf(buf[0], sizeof buf[0], "%s.attr", dbfile); 1821*ebfedea0SLionel Sambuc #else 1822*ebfedea0SLionel Sambuc BIO_snprintf(buf[0], sizeof buf[0], "%s-attr", dbfile); 1823*ebfedea0SLionel Sambuc #endif 1824*ebfedea0SLionel Sambuc dbattr_conf = NCONF_new(NULL); 1825*ebfedea0SLionel Sambuc if (NCONF_load(dbattr_conf,buf[0],&errorline) <= 0) 1826*ebfedea0SLionel Sambuc { 1827*ebfedea0SLionel Sambuc if (errorline > 0) 1828*ebfedea0SLionel Sambuc { 1829*ebfedea0SLionel Sambuc BIO_printf(bio_err, 1830*ebfedea0SLionel Sambuc "error on line %ld of db attribute file '%s'\n" 1831*ebfedea0SLionel Sambuc ,errorline,buf[0]); 1832*ebfedea0SLionel Sambuc goto err; 1833*ebfedea0SLionel Sambuc } 1834*ebfedea0SLionel Sambuc else 1835*ebfedea0SLionel Sambuc { 1836*ebfedea0SLionel Sambuc NCONF_free(dbattr_conf); 1837*ebfedea0SLionel Sambuc dbattr_conf = NULL; 1838*ebfedea0SLionel Sambuc } 1839*ebfedea0SLionel Sambuc } 1840*ebfedea0SLionel Sambuc 1841*ebfedea0SLionel Sambuc if ((retdb = OPENSSL_malloc(sizeof(CA_DB))) == NULL) 1842*ebfedea0SLionel Sambuc { 1843*ebfedea0SLionel Sambuc fprintf(stderr, "Out of memory\n"); 1844*ebfedea0SLionel Sambuc goto err; 1845*ebfedea0SLionel Sambuc } 1846*ebfedea0SLionel Sambuc 1847*ebfedea0SLionel Sambuc retdb->db = tmpdb; 1848*ebfedea0SLionel Sambuc tmpdb = NULL; 1849*ebfedea0SLionel Sambuc if (db_attr) 1850*ebfedea0SLionel Sambuc retdb->attributes = *db_attr; 1851*ebfedea0SLionel Sambuc else 1852*ebfedea0SLionel Sambuc { 1853*ebfedea0SLionel Sambuc retdb->attributes.unique_subject = 1; 1854*ebfedea0SLionel Sambuc } 1855*ebfedea0SLionel Sambuc 1856*ebfedea0SLionel Sambuc if (dbattr_conf) 1857*ebfedea0SLionel Sambuc { 1858*ebfedea0SLionel Sambuc char *p = NCONF_get_string(dbattr_conf,NULL,"unique_subject"); 1859*ebfedea0SLionel Sambuc if (p) 1860*ebfedea0SLionel Sambuc { 1861*ebfedea0SLionel Sambuc #ifdef RL_DEBUG 1862*ebfedea0SLionel Sambuc BIO_printf(bio_err, "DEBUG[load_index]: unique_subject = \"%s\"\n", p); 1863*ebfedea0SLionel Sambuc #endif 1864*ebfedea0SLionel Sambuc retdb->attributes.unique_subject = parse_yesno(p,1); 1865*ebfedea0SLionel Sambuc } 1866*ebfedea0SLionel Sambuc } 1867*ebfedea0SLionel Sambuc 1868*ebfedea0SLionel Sambuc err: 1869*ebfedea0SLionel Sambuc if (dbattr_conf) NCONF_free(dbattr_conf); 1870*ebfedea0SLionel Sambuc if (tmpdb) TXT_DB_free(tmpdb); 1871*ebfedea0SLionel Sambuc if (in) BIO_free_all(in); 1872*ebfedea0SLionel Sambuc return retdb; 1873*ebfedea0SLionel Sambuc } 1874*ebfedea0SLionel Sambuc 1875*ebfedea0SLionel Sambuc int index_index(CA_DB *db) 1876*ebfedea0SLionel Sambuc { 1877*ebfedea0SLionel Sambuc if (!TXT_DB_create_index(db->db, DB_serial, NULL, 1878*ebfedea0SLionel Sambuc LHASH_HASH_FN(index_serial), 1879*ebfedea0SLionel Sambuc LHASH_COMP_FN(index_serial))) 1880*ebfedea0SLionel Sambuc { 1881*ebfedea0SLionel Sambuc BIO_printf(bio_err, 1882*ebfedea0SLionel Sambuc "error creating serial number index:(%ld,%ld,%ld)\n", 1883*ebfedea0SLionel Sambuc db->db->error,db->db->arg1,db->db->arg2); 1884*ebfedea0SLionel Sambuc return 0; 1885*ebfedea0SLionel Sambuc } 1886*ebfedea0SLionel Sambuc 1887*ebfedea0SLionel Sambuc if (db->attributes.unique_subject 1888*ebfedea0SLionel Sambuc && !TXT_DB_create_index(db->db, DB_name, index_name_qual, 1889*ebfedea0SLionel Sambuc LHASH_HASH_FN(index_name), 1890*ebfedea0SLionel Sambuc LHASH_COMP_FN(index_name))) 1891*ebfedea0SLionel Sambuc { 1892*ebfedea0SLionel Sambuc BIO_printf(bio_err,"error creating name index:(%ld,%ld,%ld)\n", 1893*ebfedea0SLionel Sambuc db->db->error,db->db->arg1,db->db->arg2); 1894*ebfedea0SLionel Sambuc return 0; 1895*ebfedea0SLionel Sambuc } 1896*ebfedea0SLionel Sambuc return 1; 1897*ebfedea0SLionel Sambuc } 1898*ebfedea0SLionel Sambuc 1899*ebfedea0SLionel Sambuc int save_index(const char *dbfile, const char *suffix, CA_DB *db) 1900*ebfedea0SLionel Sambuc { 1901*ebfedea0SLionel Sambuc char buf[3][BSIZE]; 1902*ebfedea0SLionel Sambuc BIO *out = BIO_new(BIO_s_file()); 1903*ebfedea0SLionel Sambuc int j; 1904*ebfedea0SLionel Sambuc 1905*ebfedea0SLionel Sambuc if (out == NULL) 1906*ebfedea0SLionel Sambuc { 1907*ebfedea0SLionel Sambuc ERR_print_errors(bio_err); 1908*ebfedea0SLionel Sambuc goto err; 1909*ebfedea0SLionel Sambuc } 1910*ebfedea0SLionel Sambuc 1911*ebfedea0SLionel Sambuc j = strlen(dbfile) + strlen(suffix); 1912*ebfedea0SLionel Sambuc if (j + 6 >= BSIZE) 1913*ebfedea0SLionel Sambuc { 1914*ebfedea0SLionel Sambuc BIO_printf(bio_err,"file name too long\n"); 1915*ebfedea0SLionel Sambuc goto err; 1916*ebfedea0SLionel Sambuc } 1917*ebfedea0SLionel Sambuc 1918*ebfedea0SLionel Sambuc #ifndef OPENSSL_SYS_VMS 1919*ebfedea0SLionel Sambuc j = BIO_snprintf(buf[2], sizeof buf[2], "%s.attr", dbfile); 1920*ebfedea0SLionel Sambuc #else 1921*ebfedea0SLionel Sambuc j = BIO_snprintf(buf[2], sizeof buf[2], "%s-attr", dbfile); 1922*ebfedea0SLionel Sambuc #endif 1923*ebfedea0SLionel Sambuc #ifndef OPENSSL_SYS_VMS 1924*ebfedea0SLionel Sambuc j = BIO_snprintf(buf[1], sizeof buf[1], "%s.attr.%s", dbfile, suffix); 1925*ebfedea0SLionel Sambuc #else 1926*ebfedea0SLionel Sambuc j = BIO_snprintf(buf[1], sizeof buf[1], "%s-attr-%s", dbfile, suffix); 1927*ebfedea0SLionel Sambuc #endif 1928*ebfedea0SLionel Sambuc #ifndef OPENSSL_SYS_VMS 1929*ebfedea0SLionel Sambuc j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", dbfile, suffix); 1930*ebfedea0SLionel Sambuc #else 1931*ebfedea0SLionel Sambuc j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", dbfile, suffix); 1932*ebfedea0SLionel Sambuc #endif 1933*ebfedea0SLionel Sambuc #ifdef RL_DEBUG 1934*ebfedea0SLionel Sambuc BIO_printf(bio_err, "DEBUG: writing \"%s\"\n", buf[0]); 1935*ebfedea0SLionel Sambuc #endif 1936*ebfedea0SLionel Sambuc if (BIO_write_filename(out,buf[0]) <= 0) 1937*ebfedea0SLionel Sambuc { 1938*ebfedea0SLionel Sambuc perror(dbfile); 1939*ebfedea0SLionel Sambuc BIO_printf(bio_err,"unable to open '%s'\n", dbfile); 1940*ebfedea0SLionel Sambuc goto err; 1941*ebfedea0SLionel Sambuc } 1942*ebfedea0SLionel Sambuc j=TXT_DB_write(out,db->db); 1943*ebfedea0SLionel Sambuc if (j <= 0) goto err; 1944*ebfedea0SLionel Sambuc 1945*ebfedea0SLionel Sambuc BIO_free(out); 1946*ebfedea0SLionel Sambuc 1947*ebfedea0SLionel Sambuc out = BIO_new(BIO_s_file()); 1948*ebfedea0SLionel Sambuc #ifdef RL_DEBUG 1949*ebfedea0SLionel Sambuc BIO_printf(bio_err, "DEBUG: writing \"%s\"\n", buf[1]); 1950*ebfedea0SLionel Sambuc #endif 1951*ebfedea0SLionel Sambuc if (BIO_write_filename(out,buf[1]) <= 0) 1952*ebfedea0SLionel Sambuc { 1953*ebfedea0SLionel Sambuc perror(buf[2]); 1954*ebfedea0SLionel Sambuc BIO_printf(bio_err,"unable to open '%s'\n", buf[2]); 1955*ebfedea0SLionel Sambuc goto err; 1956*ebfedea0SLionel Sambuc } 1957*ebfedea0SLionel Sambuc BIO_printf(out,"unique_subject = %s\n", 1958*ebfedea0SLionel Sambuc db->attributes.unique_subject ? "yes" : "no"); 1959*ebfedea0SLionel Sambuc BIO_free(out); 1960*ebfedea0SLionel Sambuc 1961*ebfedea0SLionel Sambuc return 1; 1962*ebfedea0SLionel Sambuc err: 1963*ebfedea0SLionel Sambuc return 0; 1964*ebfedea0SLionel Sambuc } 1965*ebfedea0SLionel Sambuc 1966*ebfedea0SLionel Sambuc int rotate_index(const char *dbfile, const char *new_suffix, const char *old_suffix) 1967*ebfedea0SLionel Sambuc { 1968*ebfedea0SLionel Sambuc char buf[5][BSIZE]; 1969*ebfedea0SLionel Sambuc int i,j; 1970*ebfedea0SLionel Sambuc 1971*ebfedea0SLionel Sambuc i = strlen(dbfile) + strlen(old_suffix); 1972*ebfedea0SLionel Sambuc j = strlen(dbfile) + strlen(new_suffix); 1973*ebfedea0SLionel Sambuc if (i > j) j = i; 1974*ebfedea0SLionel Sambuc if (j + 6 >= BSIZE) 1975*ebfedea0SLionel Sambuc { 1976*ebfedea0SLionel Sambuc BIO_printf(bio_err,"file name too long\n"); 1977*ebfedea0SLionel Sambuc goto err; 1978*ebfedea0SLionel Sambuc } 1979*ebfedea0SLionel Sambuc 1980*ebfedea0SLionel Sambuc #ifndef OPENSSL_SYS_VMS 1981*ebfedea0SLionel Sambuc j = BIO_snprintf(buf[4], sizeof buf[4], "%s.attr", dbfile); 1982*ebfedea0SLionel Sambuc #else 1983*ebfedea0SLionel Sambuc j = BIO_snprintf(buf[4], sizeof buf[4], "%s-attr", dbfile); 1984*ebfedea0SLionel Sambuc #endif 1985*ebfedea0SLionel Sambuc #ifndef OPENSSL_SYS_VMS 1986*ebfedea0SLionel Sambuc j = BIO_snprintf(buf[2], sizeof buf[2], "%s.attr.%s", 1987*ebfedea0SLionel Sambuc dbfile, new_suffix); 1988*ebfedea0SLionel Sambuc #else 1989*ebfedea0SLionel Sambuc j = BIO_snprintf(buf[2], sizeof buf[2], "%s-attr-%s", 1990*ebfedea0SLionel Sambuc dbfile, new_suffix); 1991*ebfedea0SLionel Sambuc #endif 1992*ebfedea0SLionel Sambuc #ifndef OPENSSL_SYS_VMS 1993*ebfedea0SLionel Sambuc j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", 1994*ebfedea0SLionel Sambuc dbfile, new_suffix); 1995*ebfedea0SLionel Sambuc #else 1996*ebfedea0SLionel Sambuc j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", 1997*ebfedea0SLionel Sambuc dbfile, new_suffix); 1998*ebfedea0SLionel Sambuc #endif 1999*ebfedea0SLionel Sambuc #ifndef OPENSSL_SYS_VMS 2000*ebfedea0SLionel Sambuc j = BIO_snprintf(buf[1], sizeof buf[1], "%s.%s", 2001*ebfedea0SLionel Sambuc dbfile, old_suffix); 2002*ebfedea0SLionel Sambuc #else 2003*ebfedea0SLionel Sambuc j = BIO_snprintf(buf[1], sizeof buf[1], "%s-%s", 2004*ebfedea0SLionel Sambuc dbfile, old_suffix); 2005*ebfedea0SLionel Sambuc #endif 2006*ebfedea0SLionel Sambuc #ifndef OPENSSL_SYS_VMS 2007*ebfedea0SLionel Sambuc j = BIO_snprintf(buf[3], sizeof buf[3], "%s.attr.%s", 2008*ebfedea0SLionel Sambuc dbfile, old_suffix); 2009*ebfedea0SLionel Sambuc #else 2010*ebfedea0SLionel Sambuc j = BIO_snprintf(buf[3], sizeof buf[3], "%s-attr-%s", 2011*ebfedea0SLionel Sambuc dbfile, old_suffix); 2012*ebfedea0SLionel Sambuc #endif 2013*ebfedea0SLionel Sambuc #ifdef RL_DEBUG 2014*ebfedea0SLionel Sambuc BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", 2015*ebfedea0SLionel Sambuc dbfile, buf[1]); 2016*ebfedea0SLionel Sambuc #endif 2017*ebfedea0SLionel Sambuc if (rename(dbfile,buf[1]) < 0 && errno != ENOENT 2018*ebfedea0SLionel Sambuc #ifdef ENOTDIR 2019*ebfedea0SLionel Sambuc && errno != ENOTDIR 2020*ebfedea0SLionel Sambuc #endif 2021*ebfedea0SLionel Sambuc ) { 2022*ebfedea0SLionel Sambuc BIO_printf(bio_err, 2023*ebfedea0SLionel Sambuc "unable to rename %s to %s\n", 2024*ebfedea0SLionel Sambuc dbfile, buf[1]); 2025*ebfedea0SLionel Sambuc perror("reason"); 2026*ebfedea0SLionel Sambuc goto err; 2027*ebfedea0SLionel Sambuc } 2028*ebfedea0SLionel Sambuc #ifdef RL_DEBUG 2029*ebfedea0SLionel Sambuc BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", 2030*ebfedea0SLionel Sambuc buf[0],dbfile); 2031*ebfedea0SLionel Sambuc #endif 2032*ebfedea0SLionel Sambuc if (rename(buf[0],dbfile) < 0) 2033*ebfedea0SLionel Sambuc { 2034*ebfedea0SLionel Sambuc BIO_printf(bio_err, 2035*ebfedea0SLionel Sambuc "unable to rename %s to %s\n", 2036*ebfedea0SLionel Sambuc buf[0],dbfile); 2037*ebfedea0SLionel Sambuc perror("reason"); 2038*ebfedea0SLionel Sambuc rename(buf[1],dbfile); 2039*ebfedea0SLionel Sambuc goto err; 2040*ebfedea0SLionel Sambuc } 2041*ebfedea0SLionel Sambuc #ifdef RL_DEBUG 2042*ebfedea0SLionel Sambuc BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", 2043*ebfedea0SLionel Sambuc buf[4],buf[3]); 2044*ebfedea0SLionel Sambuc #endif 2045*ebfedea0SLionel Sambuc if (rename(buf[4],buf[3]) < 0 && errno != ENOENT 2046*ebfedea0SLionel Sambuc #ifdef ENOTDIR 2047*ebfedea0SLionel Sambuc && errno != ENOTDIR 2048*ebfedea0SLionel Sambuc #endif 2049*ebfedea0SLionel Sambuc ) { 2050*ebfedea0SLionel Sambuc BIO_printf(bio_err, 2051*ebfedea0SLionel Sambuc "unable to rename %s to %s\n", 2052*ebfedea0SLionel Sambuc buf[4], buf[3]); 2053*ebfedea0SLionel Sambuc perror("reason"); 2054*ebfedea0SLionel Sambuc rename(dbfile,buf[0]); 2055*ebfedea0SLionel Sambuc rename(buf[1],dbfile); 2056*ebfedea0SLionel Sambuc goto err; 2057*ebfedea0SLionel Sambuc } 2058*ebfedea0SLionel Sambuc #ifdef RL_DEBUG 2059*ebfedea0SLionel Sambuc BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", 2060*ebfedea0SLionel Sambuc buf[2],buf[4]); 2061*ebfedea0SLionel Sambuc #endif 2062*ebfedea0SLionel Sambuc if (rename(buf[2],buf[4]) < 0) 2063*ebfedea0SLionel Sambuc { 2064*ebfedea0SLionel Sambuc BIO_printf(bio_err, 2065*ebfedea0SLionel Sambuc "unable to rename %s to %s\n", 2066*ebfedea0SLionel Sambuc buf[2],buf[4]); 2067*ebfedea0SLionel Sambuc perror("reason"); 2068*ebfedea0SLionel Sambuc rename(buf[3],buf[4]); 2069*ebfedea0SLionel Sambuc rename(dbfile,buf[0]); 2070*ebfedea0SLionel Sambuc rename(buf[1],dbfile); 2071*ebfedea0SLionel Sambuc goto err; 2072*ebfedea0SLionel Sambuc } 2073*ebfedea0SLionel Sambuc return 1; 2074*ebfedea0SLionel Sambuc err: 2075*ebfedea0SLionel Sambuc return 0; 2076*ebfedea0SLionel Sambuc } 2077*ebfedea0SLionel Sambuc 2078*ebfedea0SLionel Sambuc void free_index(CA_DB *db) 2079*ebfedea0SLionel Sambuc { 2080*ebfedea0SLionel Sambuc if (db) 2081*ebfedea0SLionel Sambuc { 2082*ebfedea0SLionel Sambuc if (db->db) TXT_DB_free(db->db); 2083*ebfedea0SLionel Sambuc OPENSSL_free(db); 2084*ebfedea0SLionel Sambuc } 2085*ebfedea0SLionel Sambuc } 2086*ebfedea0SLionel Sambuc 2087*ebfedea0SLionel Sambuc int parse_yesno(const char *str, int def) 2088*ebfedea0SLionel Sambuc { 2089*ebfedea0SLionel Sambuc int ret = def; 2090*ebfedea0SLionel Sambuc if (str) 2091*ebfedea0SLionel Sambuc { 2092*ebfedea0SLionel Sambuc switch (*str) 2093*ebfedea0SLionel Sambuc { 2094*ebfedea0SLionel Sambuc case 'f': /* false */ 2095*ebfedea0SLionel Sambuc case 'F': /* FALSE */ 2096*ebfedea0SLionel Sambuc case 'n': /* no */ 2097*ebfedea0SLionel Sambuc case 'N': /* NO */ 2098*ebfedea0SLionel Sambuc case '0': /* 0 */ 2099*ebfedea0SLionel Sambuc ret = 0; 2100*ebfedea0SLionel Sambuc break; 2101*ebfedea0SLionel Sambuc case 't': /* true */ 2102*ebfedea0SLionel Sambuc case 'T': /* TRUE */ 2103*ebfedea0SLionel Sambuc case 'y': /* yes */ 2104*ebfedea0SLionel Sambuc case 'Y': /* YES */ 2105*ebfedea0SLionel Sambuc case '1': /* 1 */ 2106*ebfedea0SLionel Sambuc ret = 1; 2107*ebfedea0SLionel Sambuc break; 2108*ebfedea0SLionel Sambuc default: 2109*ebfedea0SLionel Sambuc ret = def; 2110*ebfedea0SLionel Sambuc break; 2111*ebfedea0SLionel Sambuc } 2112*ebfedea0SLionel Sambuc } 2113*ebfedea0SLionel Sambuc return ret; 2114*ebfedea0SLionel Sambuc } 2115*ebfedea0SLionel Sambuc 2116*ebfedea0SLionel Sambuc /* 2117*ebfedea0SLionel Sambuc * subject is expected to be in the format /type0=value0/type1=value1/type2=... 2118*ebfedea0SLionel Sambuc * where characters may be escaped by \ 2119*ebfedea0SLionel Sambuc */ 2120*ebfedea0SLionel Sambuc X509_NAME *parse_name(char *subject, long chtype, int multirdn) 2121*ebfedea0SLionel Sambuc { 2122*ebfedea0SLionel Sambuc size_t buflen = strlen(subject)+1; /* to copy the types and values into. due to escaping, the copy can only become shorter */ 2123*ebfedea0SLionel Sambuc char *buf = OPENSSL_malloc(buflen); 2124*ebfedea0SLionel Sambuc size_t max_ne = buflen / 2 + 1; /* maximum number of name elements */ 2125*ebfedea0SLionel Sambuc char **ne_types = OPENSSL_malloc(max_ne * sizeof (char *)); 2126*ebfedea0SLionel Sambuc char **ne_values = OPENSSL_malloc(max_ne * sizeof (char *)); 2127*ebfedea0SLionel Sambuc int *mval = OPENSSL_malloc (max_ne * sizeof (int)); 2128*ebfedea0SLionel Sambuc 2129*ebfedea0SLionel Sambuc char *sp = subject, *bp = buf; 2130*ebfedea0SLionel Sambuc int i, ne_num = 0; 2131*ebfedea0SLionel Sambuc 2132*ebfedea0SLionel Sambuc X509_NAME *n = NULL; 2133*ebfedea0SLionel Sambuc int nid; 2134*ebfedea0SLionel Sambuc 2135*ebfedea0SLionel Sambuc if (!buf || !ne_types || !ne_values || !mval) 2136*ebfedea0SLionel Sambuc { 2137*ebfedea0SLionel Sambuc BIO_printf(bio_err, "malloc error\n"); 2138*ebfedea0SLionel Sambuc goto error; 2139*ebfedea0SLionel Sambuc } 2140*ebfedea0SLionel Sambuc 2141*ebfedea0SLionel Sambuc if (*subject != '/') 2142*ebfedea0SLionel Sambuc { 2143*ebfedea0SLionel Sambuc BIO_printf(bio_err, "Subject does not start with '/'.\n"); 2144*ebfedea0SLionel Sambuc goto error; 2145*ebfedea0SLionel Sambuc } 2146*ebfedea0SLionel Sambuc sp++; /* skip leading / */ 2147*ebfedea0SLionel Sambuc 2148*ebfedea0SLionel Sambuc /* no multivalued RDN by default */ 2149*ebfedea0SLionel Sambuc mval[ne_num] = 0; 2150*ebfedea0SLionel Sambuc 2151*ebfedea0SLionel Sambuc while (*sp) 2152*ebfedea0SLionel Sambuc { 2153*ebfedea0SLionel Sambuc /* collect type */ 2154*ebfedea0SLionel Sambuc ne_types[ne_num] = bp; 2155*ebfedea0SLionel Sambuc while (*sp) 2156*ebfedea0SLionel Sambuc { 2157*ebfedea0SLionel Sambuc if (*sp == '\\') /* is there anything to escape in the type...? */ 2158*ebfedea0SLionel Sambuc { 2159*ebfedea0SLionel Sambuc if (*++sp) 2160*ebfedea0SLionel Sambuc *bp++ = *sp++; 2161*ebfedea0SLionel Sambuc else 2162*ebfedea0SLionel Sambuc { 2163*ebfedea0SLionel Sambuc BIO_printf(bio_err, "escape character at end of string\n"); 2164*ebfedea0SLionel Sambuc goto error; 2165*ebfedea0SLionel Sambuc } 2166*ebfedea0SLionel Sambuc } 2167*ebfedea0SLionel Sambuc else if (*sp == '=') 2168*ebfedea0SLionel Sambuc { 2169*ebfedea0SLionel Sambuc sp++; 2170*ebfedea0SLionel Sambuc *bp++ = '\0'; 2171*ebfedea0SLionel Sambuc break; 2172*ebfedea0SLionel Sambuc } 2173*ebfedea0SLionel Sambuc else 2174*ebfedea0SLionel Sambuc *bp++ = *sp++; 2175*ebfedea0SLionel Sambuc } 2176*ebfedea0SLionel Sambuc if (!*sp) 2177*ebfedea0SLionel Sambuc { 2178*ebfedea0SLionel Sambuc BIO_printf(bio_err, "end of string encountered while processing type of subject name element #%d\n", ne_num); 2179*ebfedea0SLionel Sambuc goto error; 2180*ebfedea0SLionel Sambuc } 2181*ebfedea0SLionel Sambuc ne_values[ne_num] = bp; 2182*ebfedea0SLionel Sambuc while (*sp) 2183*ebfedea0SLionel Sambuc { 2184*ebfedea0SLionel Sambuc if (*sp == '\\') 2185*ebfedea0SLionel Sambuc { 2186*ebfedea0SLionel Sambuc if (*++sp) 2187*ebfedea0SLionel Sambuc *bp++ = *sp++; 2188*ebfedea0SLionel Sambuc else 2189*ebfedea0SLionel Sambuc { 2190*ebfedea0SLionel Sambuc BIO_printf(bio_err, "escape character at end of string\n"); 2191*ebfedea0SLionel Sambuc goto error; 2192*ebfedea0SLionel Sambuc } 2193*ebfedea0SLionel Sambuc } 2194*ebfedea0SLionel Sambuc else if (*sp == '/') 2195*ebfedea0SLionel Sambuc { 2196*ebfedea0SLionel Sambuc sp++; 2197*ebfedea0SLionel Sambuc /* no multivalued RDN by default */ 2198*ebfedea0SLionel Sambuc mval[ne_num+1] = 0; 2199*ebfedea0SLionel Sambuc break; 2200*ebfedea0SLionel Sambuc } 2201*ebfedea0SLionel Sambuc else if (*sp == '+' && multirdn) 2202*ebfedea0SLionel Sambuc { 2203*ebfedea0SLionel Sambuc /* a not escaped + signals a mutlivalued RDN */ 2204*ebfedea0SLionel Sambuc sp++; 2205*ebfedea0SLionel Sambuc mval[ne_num+1] = -1; 2206*ebfedea0SLionel Sambuc break; 2207*ebfedea0SLionel Sambuc } 2208*ebfedea0SLionel Sambuc else 2209*ebfedea0SLionel Sambuc *bp++ = *sp++; 2210*ebfedea0SLionel Sambuc } 2211*ebfedea0SLionel Sambuc *bp++ = '\0'; 2212*ebfedea0SLionel Sambuc ne_num++; 2213*ebfedea0SLionel Sambuc } 2214*ebfedea0SLionel Sambuc 2215*ebfedea0SLionel Sambuc if (!(n = X509_NAME_new())) 2216*ebfedea0SLionel Sambuc goto error; 2217*ebfedea0SLionel Sambuc 2218*ebfedea0SLionel Sambuc for (i = 0; i < ne_num; i++) 2219*ebfedea0SLionel Sambuc { 2220*ebfedea0SLionel Sambuc if ((nid=OBJ_txt2nid(ne_types[i])) == NID_undef) 2221*ebfedea0SLionel Sambuc { 2222*ebfedea0SLionel Sambuc BIO_printf(bio_err, "Subject Attribute %s has no known NID, skipped\n", ne_types[i]); 2223*ebfedea0SLionel Sambuc continue; 2224*ebfedea0SLionel Sambuc } 2225*ebfedea0SLionel Sambuc 2226*ebfedea0SLionel Sambuc if (!*ne_values[i]) 2227*ebfedea0SLionel Sambuc { 2228*ebfedea0SLionel Sambuc BIO_printf(bio_err, "No value provided for Subject Attribute %s, skipped\n", ne_types[i]); 2229*ebfedea0SLionel Sambuc continue; 2230*ebfedea0SLionel Sambuc } 2231*ebfedea0SLionel Sambuc 2232*ebfedea0SLionel Sambuc if (!X509_NAME_add_entry_by_NID(n, nid, chtype, (unsigned char*)ne_values[i], -1,-1,mval[i])) 2233*ebfedea0SLionel Sambuc goto error; 2234*ebfedea0SLionel Sambuc } 2235*ebfedea0SLionel Sambuc 2236*ebfedea0SLionel Sambuc OPENSSL_free(ne_values); 2237*ebfedea0SLionel Sambuc OPENSSL_free(ne_types); 2238*ebfedea0SLionel Sambuc OPENSSL_free(buf); 2239*ebfedea0SLionel Sambuc OPENSSL_free(mval); 2240*ebfedea0SLionel Sambuc return n; 2241*ebfedea0SLionel Sambuc 2242*ebfedea0SLionel Sambuc error: 2243*ebfedea0SLionel Sambuc X509_NAME_free(n); 2244*ebfedea0SLionel Sambuc if (ne_values) 2245*ebfedea0SLionel Sambuc OPENSSL_free(ne_values); 2246*ebfedea0SLionel Sambuc if (ne_types) 2247*ebfedea0SLionel Sambuc OPENSSL_free(ne_types); 2248*ebfedea0SLionel Sambuc if (mval) 2249*ebfedea0SLionel Sambuc OPENSSL_free(mval); 2250*ebfedea0SLionel Sambuc if (buf) 2251*ebfedea0SLionel Sambuc OPENSSL_free(buf); 2252*ebfedea0SLionel Sambuc return NULL; 2253*ebfedea0SLionel Sambuc } 2254*ebfedea0SLionel Sambuc 2255*ebfedea0SLionel Sambuc int args_verify(char ***pargs, int *pargc, 2256*ebfedea0SLionel Sambuc int *badarg, BIO *err, X509_VERIFY_PARAM **pm) 2257*ebfedea0SLionel Sambuc { 2258*ebfedea0SLionel Sambuc ASN1_OBJECT *otmp = NULL; 2259*ebfedea0SLionel Sambuc unsigned long flags = 0; 2260*ebfedea0SLionel Sambuc int i; 2261*ebfedea0SLionel Sambuc int purpose = 0, depth = -1; 2262*ebfedea0SLionel Sambuc char **oldargs = *pargs; 2263*ebfedea0SLionel Sambuc char *arg = **pargs, *argn = (*pargs)[1]; 2264*ebfedea0SLionel Sambuc time_t at_time = 0; 2265*ebfedea0SLionel Sambuc if (!strcmp(arg, "-policy")) 2266*ebfedea0SLionel Sambuc { 2267*ebfedea0SLionel Sambuc if (!argn) 2268*ebfedea0SLionel Sambuc *badarg = 1; 2269*ebfedea0SLionel Sambuc else 2270*ebfedea0SLionel Sambuc { 2271*ebfedea0SLionel Sambuc otmp = OBJ_txt2obj(argn, 0); 2272*ebfedea0SLionel Sambuc if (!otmp) 2273*ebfedea0SLionel Sambuc { 2274*ebfedea0SLionel Sambuc BIO_printf(err, "Invalid Policy \"%s\"\n", 2275*ebfedea0SLionel Sambuc argn); 2276*ebfedea0SLionel Sambuc *badarg = 1; 2277*ebfedea0SLionel Sambuc } 2278*ebfedea0SLionel Sambuc } 2279*ebfedea0SLionel Sambuc (*pargs)++; 2280*ebfedea0SLionel Sambuc } 2281*ebfedea0SLionel Sambuc else if (strcmp(arg,"-purpose") == 0) 2282*ebfedea0SLionel Sambuc { 2283*ebfedea0SLionel Sambuc X509_PURPOSE *xptmp; 2284*ebfedea0SLionel Sambuc if (!argn) 2285*ebfedea0SLionel Sambuc *badarg = 1; 2286*ebfedea0SLionel Sambuc else 2287*ebfedea0SLionel Sambuc { 2288*ebfedea0SLionel Sambuc i = X509_PURPOSE_get_by_sname(argn); 2289*ebfedea0SLionel Sambuc if(i < 0) 2290*ebfedea0SLionel Sambuc { 2291*ebfedea0SLionel Sambuc BIO_printf(err, "unrecognized purpose\n"); 2292*ebfedea0SLionel Sambuc *badarg = 1; 2293*ebfedea0SLionel Sambuc } 2294*ebfedea0SLionel Sambuc else 2295*ebfedea0SLionel Sambuc { 2296*ebfedea0SLionel Sambuc xptmp = X509_PURPOSE_get0(i); 2297*ebfedea0SLionel Sambuc purpose = X509_PURPOSE_get_id(xptmp); 2298*ebfedea0SLionel Sambuc } 2299*ebfedea0SLionel Sambuc } 2300*ebfedea0SLionel Sambuc (*pargs)++; 2301*ebfedea0SLionel Sambuc } 2302*ebfedea0SLionel Sambuc else if (strcmp(arg,"-verify_depth") == 0) 2303*ebfedea0SLionel Sambuc { 2304*ebfedea0SLionel Sambuc if (!argn) 2305*ebfedea0SLionel Sambuc *badarg = 1; 2306*ebfedea0SLionel Sambuc else 2307*ebfedea0SLionel Sambuc { 2308*ebfedea0SLionel Sambuc depth = atoi(argn); 2309*ebfedea0SLionel Sambuc if(depth < 0) 2310*ebfedea0SLionel Sambuc { 2311*ebfedea0SLionel Sambuc BIO_printf(err, "invalid depth\n"); 2312*ebfedea0SLionel Sambuc *badarg = 1; 2313*ebfedea0SLionel Sambuc } 2314*ebfedea0SLionel Sambuc } 2315*ebfedea0SLionel Sambuc (*pargs)++; 2316*ebfedea0SLionel Sambuc } 2317*ebfedea0SLionel Sambuc else if (strcmp(arg,"-attime") == 0) 2318*ebfedea0SLionel Sambuc { 2319*ebfedea0SLionel Sambuc if (!argn) 2320*ebfedea0SLionel Sambuc *badarg = 1; 2321*ebfedea0SLionel Sambuc else 2322*ebfedea0SLionel Sambuc { 2323*ebfedea0SLionel Sambuc long timestamp; 2324*ebfedea0SLionel Sambuc /* interpret the -attime argument as seconds since 2325*ebfedea0SLionel Sambuc * Epoch */ 2326*ebfedea0SLionel Sambuc if (sscanf(argn, "%li", ×tamp) != 1) 2327*ebfedea0SLionel Sambuc { 2328*ebfedea0SLionel Sambuc BIO_printf(bio_err, 2329*ebfedea0SLionel Sambuc "Error parsing timestamp %s\n", 2330*ebfedea0SLionel Sambuc argn); 2331*ebfedea0SLionel Sambuc *badarg = 1; 2332*ebfedea0SLionel Sambuc } 2333*ebfedea0SLionel Sambuc /* on some platforms time_t may be a float */ 2334*ebfedea0SLionel Sambuc at_time = (time_t) timestamp; 2335*ebfedea0SLionel Sambuc } 2336*ebfedea0SLionel Sambuc (*pargs)++; 2337*ebfedea0SLionel Sambuc } 2338*ebfedea0SLionel Sambuc else if (!strcmp(arg, "-ignore_critical")) 2339*ebfedea0SLionel Sambuc flags |= X509_V_FLAG_IGNORE_CRITICAL; 2340*ebfedea0SLionel Sambuc else if (!strcmp(arg, "-issuer_checks")) 2341*ebfedea0SLionel Sambuc flags |= X509_V_FLAG_CB_ISSUER_CHECK; 2342*ebfedea0SLionel Sambuc else if (!strcmp(arg, "-crl_check")) 2343*ebfedea0SLionel Sambuc flags |= X509_V_FLAG_CRL_CHECK; 2344*ebfedea0SLionel Sambuc else if (!strcmp(arg, "-crl_check_all")) 2345*ebfedea0SLionel Sambuc flags |= X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL; 2346*ebfedea0SLionel Sambuc else if (!strcmp(arg, "-policy_check")) 2347*ebfedea0SLionel Sambuc flags |= X509_V_FLAG_POLICY_CHECK; 2348*ebfedea0SLionel Sambuc else if (!strcmp(arg, "-explicit_policy")) 2349*ebfedea0SLionel Sambuc flags |= X509_V_FLAG_EXPLICIT_POLICY; 2350*ebfedea0SLionel Sambuc else if (!strcmp(arg, "-inhibit_any")) 2351*ebfedea0SLionel Sambuc flags |= X509_V_FLAG_INHIBIT_ANY; 2352*ebfedea0SLionel Sambuc else if (!strcmp(arg, "-inhibit_map")) 2353*ebfedea0SLionel Sambuc flags |= X509_V_FLAG_INHIBIT_MAP; 2354*ebfedea0SLionel Sambuc else if (!strcmp(arg, "-x509_strict")) 2355*ebfedea0SLionel Sambuc flags |= X509_V_FLAG_X509_STRICT; 2356*ebfedea0SLionel Sambuc else if (!strcmp(arg, "-extended_crl")) 2357*ebfedea0SLionel Sambuc flags |= X509_V_FLAG_EXTENDED_CRL_SUPPORT; 2358*ebfedea0SLionel Sambuc else if (!strcmp(arg, "-use_deltas")) 2359*ebfedea0SLionel Sambuc flags |= X509_V_FLAG_USE_DELTAS; 2360*ebfedea0SLionel Sambuc else if (!strcmp(arg, "-policy_print")) 2361*ebfedea0SLionel Sambuc flags |= X509_V_FLAG_NOTIFY_POLICY; 2362*ebfedea0SLionel Sambuc else if (!strcmp(arg, "-check_ss_sig")) 2363*ebfedea0SLionel Sambuc flags |= X509_V_FLAG_CHECK_SS_SIGNATURE; 2364*ebfedea0SLionel Sambuc else 2365*ebfedea0SLionel Sambuc return 0; 2366*ebfedea0SLionel Sambuc 2367*ebfedea0SLionel Sambuc if (*badarg) 2368*ebfedea0SLionel Sambuc { 2369*ebfedea0SLionel Sambuc if (*pm) 2370*ebfedea0SLionel Sambuc X509_VERIFY_PARAM_free(*pm); 2371*ebfedea0SLionel Sambuc *pm = NULL; 2372*ebfedea0SLionel Sambuc goto end; 2373*ebfedea0SLionel Sambuc } 2374*ebfedea0SLionel Sambuc 2375*ebfedea0SLionel Sambuc if (!*pm && !(*pm = X509_VERIFY_PARAM_new())) 2376*ebfedea0SLionel Sambuc { 2377*ebfedea0SLionel Sambuc *badarg = 1; 2378*ebfedea0SLionel Sambuc goto end; 2379*ebfedea0SLionel Sambuc } 2380*ebfedea0SLionel Sambuc 2381*ebfedea0SLionel Sambuc if (otmp) 2382*ebfedea0SLionel Sambuc X509_VERIFY_PARAM_add0_policy(*pm, otmp); 2383*ebfedea0SLionel Sambuc if (flags) 2384*ebfedea0SLionel Sambuc X509_VERIFY_PARAM_set_flags(*pm, flags); 2385*ebfedea0SLionel Sambuc 2386*ebfedea0SLionel Sambuc if (purpose) 2387*ebfedea0SLionel Sambuc X509_VERIFY_PARAM_set_purpose(*pm, purpose); 2388*ebfedea0SLionel Sambuc 2389*ebfedea0SLionel Sambuc if (depth >= 0) 2390*ebfedea0SLionel Sambuc X509_VERIFY_PARAM_set_depth(*pm, depth); 2391*ebfedea0SLionel Sambuc 2392*ebfedea0SLionel Sambuc if (at_time) 2393*ebfedea0SLionel Sambuc X509_VERIFY_PARAM_set_time(*pm, at_time); 2394*ebfedea0SLionel Sambuc 2395*ebfedea0SLionel Sambuc end: 2396*ebfedea0SLionel Sambuc 2397*ebfedea0SLionel Sambuc (*pargs)++; 2398*ebfedea0SLionel Sambuc 2399*ebfedea0SLionel Sambuc if (pargc) 2400*ebfedea0SLionel Sambuc *pargc -= *pargs - oldargs; 2401*ebfedea0SLionel Sambuc 2402*ebfedea0SLionel Sambuc return 1; 2403*ebfedea0SLionel Sambuc 2404*ebfedea0SLionel Sambuc } 2405*ebfedea0SLionel Sambuc 2406*ebfedea0SLionel Sambuc /* Read whole contents of a BIO into an allocated memory buffer and 2407*ebfedea0SLionel Sambuc * return it. 2408*ebfedea0SLionel Sambuc */ 2409*ebfedea0SLionel Sambuc 2410*ebfedea0SLionel Sambuc int bio_to_mem(unsigned char **out, int maxlen, BIO *in) 2411*ebfedea0SLionel Sambuc { 2412*ebfedea0SLionel Sambuc BIO *mem; 2413*ebfedea0SLionel Sambuc int len, ret; 2414*ebfedea0SLionel Sambuc unsigned char tbuf[1024]; 2415*ebfedea0SLionel Sambuc mem = BIO_new(BIO_s_mem()); 2416*ebfedea0SLionel Sambuc if (!mem) 2417*ebfedea0SLionel Sambuc return -1; 2418*ebfedea0SLionel Sambuc for(;;) 2419*ebfedea0SLionel Sambuc { 2420*ebfedea0SLionel Sambuc if ((maxlen != -1) && maxlen < 1024) 2421*ebfedea0SLionel Sambuc len = maxlen; 2422*ebfedea0SLionel Sambuc else 2423*ebfedea0SLionel Sambuc len = 1024; 2424*ebfedea0SLionel Sambuc len = BIO_read(in, tbuf, len); 2425*ebfedea0SLionel Sambuc if (len <= 0) 2426*ebfedea0SLionel Sambuc break; 2427*ebfedea0SLionel Sambuc if (BIO_write(mem, tbuf, len) != len) 2428*ebfedea0SLionel Sambuc { 2429*ebfedea0SLionel Sambuc BIO_free(mem); 2430*ebfedea0SLionel Sambuc return -1; 2431*ebfedea0SLionel Sambuc } 2432*ebfedea0SLionel Sambuc maxlen -= len; 2433*ebfedea0SLionel Sambuc 2434*ebfedea0SLionel Sambuc if (maxlen == 0) 2435*ebfedea0SLionel Sambuc break; 2436*ebfedea0SLionel Sambuc } 2437*ebfedea0SLionel Sambuc ret = BIO_get_mem_data(mem, (char **)out); 2438*ebfedea0SLionel Sambuc BIO_set_flags(mem, BIO_FLAGS_MEM_RDONLY); 2439*ebfedea0SLionel Sambuc BIO_free(mem); 2440*ebfedea0SLionel Sambuc return ret; 2441*ebfedea0SLionel Sambuc } 2442*ebfedea0SLionel Sambuc 2443*ebfedea0SLionel Sambuc int pkey_ctrl_string(EVP_PKEY_CTX *ctx, char *value) 2444*ebfedea0SLionel Sambuc { 2445*ebfedea0SLionel Sambuc int rv; 2446*ebfedea0SLionel Sambuc char *stmp, *vtmp = NULL; 2447*ebfedea0SLionel Sambuc stmp = BUF_strdup(value); 2448*ebfedea0SLionel Sambuc if (!stmp) 2449*ebfedea0SLionel Sambuc return -1; 2450*ebfedea0SLionel Sambuc vtmp = strchr(stmp, ':'); 2451*ebfedea0SLionel Sambuc if (vtmp) 2452*ebfedea0SLionel Sambuc { 2453*ebfedea0SLionel Sambuc *vtmp = 0; 2454*ebfedea0SLionel Sambuc vtmp++; 2455*ebfedea0SLionel Sambuc } 2456*ebfedea0SLionel Sambuc rv = EVP_PKEY_CTX_ctrl_str(ctx, stmp, vtmp); 2457*ebfedea0SLionel Sambuc OPENSSL_free(stmp); 2458*ebfedea0SLionel Sambuc return rv; 2459*ebfedea0SLionel Sambuc } 2460*ebfedea0SLionel Sambuc 2461*ebfedea0SLionel Sambuc static void nodes_print(BIO *out, const char *name, 2462*ebfedea0SLionel Sambuc STACK_OF(X509_POLICY_NODE) *nodes) 2463*ebfedea0SLionel Sambuc { 2464*ebfedea0SLionel Sambuc X509_POLICY_NODE *node; 2465*ebfedea0SLionel Sambuc int i; 2466*ebfedea0SLionel Sambuc BIO_printf(out, "%s Policies:", name); 2467*ebfedea0SLionel Sambuc if (nodes) 2468*ebfedea0SLionel Sambuc { 2469*ebfedea0SLionel Sambuc BIO_puts(out, "\n"); 2470*ebfedea0SLionel Sambuc for (i = 0; i < sk_X509_POLICY_NODE_num(nodes); i++) 2471*ebfedea0SLionel Sambuc { 2472*ebfedea0SLionel Sambuc node = sk_X509_POLICY_NODE_value(nodes, i); 2473*ebfedea0SLionel Sambuc X509_POLICY_NODE_print(out, node, 2); 2474*ebfedea0SLionel Sambuc } 2475*ebfedea0SLionel Sambuc } 2476*ebfedea0SLionel Sambuc else 2477*ebfedea0SLionel Sambuc BIO_puts(out, " <empty>\n"); 2478*ebfedea0SLionel Sambuc } 2479*ebfedea0SLionel Sambuc 2480*ebfedea0SLionel Sambuc void policies_print(BIO *out, X509_STORE_CTX *ctx) 2481*ebfedea0SLionel Sambuc { 2482*ebfedea0SLionel Sambuc X509_POLICY_TREE *tree; 2483*ebfedea0SLionel Sambuc int explicit_policy; 2484*ebfedea0SLionel Sambuc int free_out = 0; 2485*ebfedea0SLionel Sambuc if (out == NULL) 2486*ebfedea0SLionel Sambuc { 2487*ebfedea0SLionel Sambuc out = BIO_new_fp(stderr, BIO_NOCLOSE); 2488*ebfedea0SLionel Sambuc free_out = 1; 2489*ebfedea0SLionel Sambuc } 2490*ebfedea0SLionel Sambuc tree = X509_STORE_CTX_get0_policy_tree(ctx); 2491*ebfedea0SLionel Sambuc explicit_policy = X509_STORE_CTX_get_explicit_policy(ctx); 2492*ebfedea0SLionel Sambuc 2493*ebfedea0SLionel Sambuc BIO_printf(out, "Require explicit Policy: %s\n", 2494*ebfedea0SLionel Sambuc explicit_policy ? "True" : "False"); 2495*ebfedea0SLionel Sambuc 2496*ebfedea0SLionel Sambuc nodes_print(out, "Authority", X509_policy_tree_get0_policies(tree)); 2497*ebfedea0SLionel Sambuc nodes_print(out, "User", X509_policy_tree_get0_user_policies(tree)); 2498*ebfedea0SLionel Sambuc if (free_out) 2499*ebfedea0SLionel Sambuc BIO_free(out); 2500*ebfedea0SLionel Sambuc } 2501*ebfedea0SLionel Sambuc 2502*ebfedea0SLionel Sambuc #if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK) 2503*ebfedea0SLionel Sambuc 2504*ebfedea0SLionel Sambuc static JPAKE_CTX *jpake_init(const char *us, const char *them, 2505*ebfedea0SLionel Sambuc const char *secret) 2506*ebfedea0SLionel Sambuc { 2507*ebfedea0SLionel Sambuc BIGNUM *p = NULL; 2508*ebfedea0SLionel Sambuc BIGNUM *g = NULL; 2509*ebfedea0SLionel Sambuc BIGNUM *q = NULL; 2510*ebfedea0SLionel Sambuc BIGNUM *bnsecret = BN_new(); 2511*ebfedea0SLionel Sambuc JPAKE_CTX *ctx; 2512*ebfedea0SLionel Sambuc 2513*ebfedea0SLionel Sambuc /* Use a safe prime for p (that we found earlier) */ 2514*ebfedea0SLionel Sambuc BN_hex2bn(&p, "F9E5B365665EA7A05A9C534502780FEE6F1AB5BD4F49947FD036DBD7E905269AF46EF28B0FC07487EE4F5D20FB3C0AF8E700F3A2FA3414970CBED44FEDFF80CE78D800F184BB82435D137AADA2C6C16523247930A63B85661D1FC817A51ACD96168E95898A1F83A79FFB529368AA7833ABD1B0C3AEDDB14D2E1A2F71D99F763F"); 2515*ebfedea0SLionel Sambuc g = BN_new(); 2516*ebfedea0SLionel Sambuc BN_set_word(g, 2); 2517*ebfedea0SLionel Sambuc q = BN_new(); 2518*ebfedea0SLionel Sambuc BN_rshift1(q, p); 2519*ebfedea0SLionel Sambuc 2520*ebfedea0SLionel Sambuc BN_bin2bn((const unsigned char *)secret, strlen(secret), bnsecret); 2521*ebfedea0SLionel Sambuc 2522*ebfedea0SLionel Sambuc ctx = JPAKE_CTX_new(us, them, p, g, q, bnsecret); 2523*ebfedea0SLionel Sambuc BN_free(bnsecret); 2524*ebfedea0SLionel Sambuc BN_free(q); 2525*ebfedea0SLionel Sambuc BN_free(g); 2526*ebfedea0SLionel Sambuc BN_free(p); 2527*ebfedea0SLionel Sambuc 2528*ebfedea0SLionel Sambuc return ctx; 2529*ebfedea0SLionel Sambuc } 2530*ebfedea0SLionel Sambuc 2531*ebfedea0SLionel Sambuc static void jpake_send_part(BIO *conn, const JPAKE_STEP_PART *p) 2532*ebfedea0SLionel Sambuc { 2533*ebfedea0SLionel Sambuc BN_print(conn, p->gx); 2534*ebfedea0SLionel Sambuc BIO_puts(conn, "\n"); 2535*ebfedea0SLionel Sambuc BN_print(conn, p->zkpx.gr); 2536*ebfedea0SLionel Sambuc BIO_puts(conn, "\n"); 2537*ebfedea0SLionel Sambuc BN_print(conn, p->zkpx.b); 2538*ebfedea0SLionel Sambuc BIO_puts(conn, "\n"); 2539*ebfedea0SLionel Sambuc } 2540*ebfedea0SLionel Sambuc 2541*ebfedea0SLionel Sambuc static void jpake_send_step1(BIO *bconn, JPAKE_CTX *ctx) 2542*ebfedea0SLionel Sambuc { 2543*ebfedea0SLionel Sambuc JPAKE_STEP1 s1; 2544*ebfedea0SLionel Sambuc 2545*ebfedea0SLionel Sambuc JPAKE_STEP1_init(&s1); 2546*ebfedea0SLionel Sambuc JPAKE_STEP1_generate(&s1, ctx); 2547*ebfedea0SLionel Sambuc jpake_send_part(bconn, &s1.p1); 2548*ebfedea0SLionel Sambuc jpake_send_part(bconn, &s1.p2); 2549*ebfedea0SLionel Sambuc (void)BIO_flush(bconn); 2550*ebfedea0SLionel Sambuc JPAKE_STEP1_release(&s1); 2551*ebfedea0SLionel Sambuc } 2552*ebfedea0SLionel Sambuc 2553*ebfedea0SLionel Sambuc static void jpake_send_step2(BIO *bconn, JPAKE_CTX *ctx) 2554*ebfedea0SLionel Sambuc { 2555*ebfedea0SLionel Sambuc JPAKE_STEP2 s2; 2556*ebfedea0SLionel Sambuc 2557*ebfedea0SLionel Sambuc JPAKE_STEP2_init(&s2); 2558*ebfedea0SLionel Sambuc JPAKE_STEP2_generate(&s2, ctx); 2559*ebfedea0SLionel Sambuc jpake_send_part(bconn, &s2); 2560*ebfedea0SLionel Sambuc (void)BIO_flush(bconn); 2561*ebfedea0SLionel Sambuc JPAKE_STEP2_release(&s2); 2562*ebfedea0SLionel Sambuc } 2563*ebfedea0SLionel Sambuc 2564*ebfedea0SLionel Sambuc static void jpake_send_step3a(BIO *bconn, JPAKE_CTX *ctx) 2565*ebfedea0SLionel Sambuc { 2566*ebfedea0SLionel Sambuc JPAKE_STEP3A s3a; 2567*ebfedea0SLionel Sambuc 2568*ebfedea0SLionel Sambuc JPAKE_STEP3A_init(&s3a); 2569*ebfedea0SLionel Sambuc JPAKE_STEP3A_generate(&s3a, ctx); 2570*ebfedea0SLionel Sambuc BIO_write(bconn, s3a.hhk, sizeof s3a.hhk); 2571*ebfedea0SLionel Sambuc (void)BIO_flush(bconn); 2572*ebfedea0SLionel Sambuc JPAKE_STEP3A_release(&s3a); 2573*ebfedea0SLionel Sambuc } 2574*ebfedea0SLionel Sambuc 2575*ebfedea0SLionel Sambuc static void jpake_send_step3b(BIO *bconn, JPAKE_CTX *ctx) 2576*ebfedea0SLionel Sambuc { 2577*ebfedea0SLionel Sambuc JPAKE_STEP3B s3b; 2578*ebfedea0SLionel Sambuc 2579*ebfedea0SLionel Sambuc JPAKE_STEP3B_init(&s3b); 2580*ebfedea0SLionel Sambuc JPAKE_STEP3B_generate(&s3b, ctx); 2581*ebfedea0SLionel Sambuc BIO_write(bconn, s3b.hk, sizeof s3b.hk); 2582*ebfedea0SLionel Sambuc (void)BIO_flush(bconn); 2583*ebfedea0SLionel Sambuc JPAKE_STEP3B_release(&s3b); 2584*ebfedea0SLionel Sambuc } 2585*ebfedea0SLionel Sambuc 2586*ebfedea0SLionel Sambuc static void readbn(BIGNUM **bn, BIO *bconn) 2587*ebfedea0SLionel Sambuc { 2588*ebfedea0SLionel Sambuc char buf[10240]; 2589*ebfedea0SLionel Sambuc int l; 2590*ebfedea0SLionel Sambuc 2591*ebfedea0SLionel Sambuc l = BIO_gets(bconn, buf, sizeof buf); 2592*ebfedea0SLionel Sambuc assert(l > 0); 2593*ebfedea0SLionel Sambuc assert(buf[l-1] == '\n'); 2594*ebfedea0SLionel Sambuc buf[l-1] = '\0'; 2595*ebfedea0SLionel Sambuc BN_hex2bn(bn, buf); 2596*ebfedea0SLionel Sambuc } 2597*ebfedea0SLionel Sambuc 2598*ebfedea0SLionel Sambuc static void jpake_receive_part(JPAKE_STEP_PART *p, BIO *bconn) 2599*ebfedea0SLionel Sambuc { 2600*ebfedea0SLionel Sambuc readbn(&p->gx, bconn); 2601*ebfedea0SLionel Sambuc readbn(&p->zkpx.gr, bconn); 2602*ebfedea0SLionel Sambuc readbn(&p->zkpx.b, bconn); 2603*ebfedea0SLionel Sambuc } 2604*ebfedea0SLionel Sambuc 2605*ebfedea0SLionel Sambuc static void jpake_receive_step1(JPAKE_CTX *ctx, BIO *bconn) 2606*ebfedea0SLionel Sambuc { 2607*ebfedea0SLionel Sambuc JPAKE_STEP1 s1; 2608*ebfedea0SLionel Sambuc 2609*ebfedea0SLionel Sambuc JPAKE_STEP1_init(&s1); 2610*ebfedea0SLionel Sambuc jpake_receive_part(&s1.p1, bconn); 2611*ebfedea0SLionel Sambuc jpake_receive_part(&s1.p2, bconn); 2612*ebfedea0SLionel Sambuc if(!JPAKE_STEP1_process(ctx, &s1)) 2613*ebfedea0SLionel Sambuc { 2614*ebfedea0SLionel Sambuc ERR_print_errors(bio_err); 2615*ebfedea0SLionel Sambuc exit(1); 2616*ebfedea0SLionel Sambuc } 2617*ebfedea0SLionel Sambuc JPAKE_STEP1_release(&s1); 2618*ebfedea0SLionel Sambuc } 2619*ebfedea0SLionel Sambuc 2620*ebfedea0SLionel Sambuc static void jpake_receive_step2(JPAKE_CTX *ctx, BIO *bconn) 2621*ebfedea0SLionel Sambuc { 2622*ebfedea0SLionel Sambuc JPAKE_STEP2 s2; 2623*ebfedea0SLionel Sambuc 2624*ebfedea0SLionel Sambuc JPAKE_STEP2_init(&s2); 2625*ebfedea0SLionel Sambuc jpake_receive_part(&s2, bconn); 2626*ebfedea0SLionel Sambuc if(!JPAKE_STEP2_process(ctx, &s2)) 2627*ebfedea0SLionel Sambuc { 2628*ebfedea0SLionel Sambuc ERR_print_errors(bio_err); 2629*ebfedea0SLionel Sambuc exit(1); 2630*ebfedea0SLionel Sambuc } 2631*ebfedea0SLionel Sambuc JPAKE_STEP2_release(&s2); 2632*ebfedea0SLionel Sambuc } 2633*ebfedea0SLionel Sambuc 2634*ebfedea0SLionel Sambuc static void jpake_receive_step3a(JPAKE_CTX *ctx, BIO *bconn) 2635*ebfedea0SLionel Sambuc { 2636*ebfedea0SLionel Sambuc JPAKE_STEP3A s3a; 2637*ebfedea0SLionel Sambuc int l; 2638*ebfedea0SLionel Sambuc 2639*ebfedea0SLionel Sambuc JPAKE_STEP3A_init(&s3a); 2640*ebfedea0SLionel Sambuc l = BIO_read(bconn, s3a.hhk, sizeof s3a.hhk); 2641*ebfedea0SLionel Sambuc assert(l == sizeof s3a.hhk); 2642*ebfedea0SLionel Sambuc if(!JPAKE_STEP3A_process(ctx, &s3a)) 2643*ebfedea0SLionel Sambuc { 2644*ebfedea0SLionel Sambuc ERR_print_errors(bio_err); 2645*ebfedea0SLionel Sambuc exit(1); 2646*ebfedea0SLionel Sambuc } 2647*ebfedea0SLionel Sambuc JPAKE_STEP3A_release(&s3a); 2648*ebfedea0SLionel Sambuc } 2649*ebfedea0SLionel Sambuc 2650*ebfedea0SLionel Sambuc static void jpake_receive_step3b(JPAKE_CTX *ctx, BIO *bconn) 2651*ebfedea0SLionel Sambuc { 2652*ebfedea0SLionel Sambuc JPAKE_STEP3B s3b; 2653*ebfedea0SLionel Sambuc int l; 2654*ebfedea0SLionel Sambuc 2655*ebfedea0SLionel Sambuc JPAKE_STEP3B_init(&s3b); 2656*ebfedea0SLionel Sambuc l = BIO_read(bconn, s3b.hk, sizeof s3b.hk); 2657*ebfedea0SLionel Sambuc assert(l == sizeof s3b.hk); 2658*ebfedea0SLionel Sambuc if(!JPAKE_STEP3B_process(ctx, &s3b)) 2659*ebfedea0SLionel Sambuc { 2660*ebfedea0SLionel Sambuc ERR_print_errors(bio_err); 2661*ebfedea0SLionel Sambuc exit(1); 2662*ebfedea0SLionel Sambuc } 2663*ebfedea0SLionel Sambuc JPAKE_STEP3B_release(&s3b); 2664*ebfedea0SLionel Sambuc } 2665*ebfedea0SLionel Sambuc 2666*ebfedea0SLionel Sambuc void jpake_client_auth(BIO *out, BIO *conn, const char *secret) 2667*ebfedea0SLionel Sambuc { 2668*ebfedea0SLionel Sambuc JPAKE_CTX *ctx; 2669*ebfedea0SLionel Sambuc BIO *bconn; 2670*ebfedea0SLionel Sambuc 2671*ebfedea0SLionel Sambuc BIO_puts(out, "Authenticating with JPAKE\n"); 2672*ebfedea0SLionel Sambuc 2673*ebfedea0SLionel Sambuc ctx = jpake_init("client", "server", secret); 2674*ebfedea0SLionel Sambuc 2675*ebfedea0SLionel Sambuc bconn = BIO_new(BIO_f_buffer()); 2676*ebfedea0SLionel Sambuc BIO_push(bconn, conn); 2677*ebfedea0SLionel Sambuc 2678*ebfedea0SLionel Sambuc jpake_send_step1(bconn, ctx); 2679*ebfedea0SLionel Sambuc jpake_receive_step1(ctx, bconn); 2680*ebfedea0SLionel Sambuc jpake_send_step2(bconn, ctx); 2681*ebfedea0SLionel Sambuc jpake_receive_step2(ctx, bconn); 2682*ebfedea0SLionel Sambuc jpake_send_step3a(bconn, ctx); 2683*ebfedea0SLionel Sambuc jpake_receive_step3b(ctx, bconn); 2684*ebfedea0SLionel Sambuc 2685*ebfedea0SLionel Sambuc BIO_puts(out, "JPAKE authentication succeeded, setting PSK\n"); 2686*ebfedea0SLionel Sambuc 2687*ebfedea0SLionel Sambuc psk_key = BN_bn2hex(JPAKE_get_shared_key(ctx)); 2688*ebfedea0SLionel Sambuc 2689*ebfedea0SLionel Sambuc BIO_pop(bconn); 2690*ebfedea0SLionel Sambuc BIO_free(bconn); 2691*ebfedea0SLionel Sambuc 2692*ebfedea0SLionel Sambuc JPAKE_CTX_free(ctx); 2693*ebfedea0SLionel Sambuc } 2694*ebfedea0SLionel Sambuc 2695*ebfedea0SLionel Sambuc void jpake_server_auth(BIO *out, BIO *conn, const char *secret) 2696*ebfedea0SLionel Sambuc { 2697*ebfedea0SLionel Sambuc JPAKE_CTX *ctx; 2698*ebfedea0SLionel Sambuc BIO *bconn; 2699*ebfedea0SLionel Sambuc 2700*ebfedea0SLionel Sambuc BIO_puts(out, "Authenticating with JPAKE\n"); 2701*ebfedea0SLionel Sambuc 2702*ebfedea0SLionel Sambuc ctx = jpake_init("server", "client", secret); 2703*ebfedea0SLionel Sambuc 2704*ebfedea0SLionel Sambuc bconn = BIO_new(BIO_f_buffer()); 2705*ebfedea0SLionel Sambuc BIO_push(bconn, conn); 2706*ebfedea0SLionel Sambuc 2707*ebfedea0SLionel Sambuc jpake_receive_step1(ctx, bconn); 2708*ebfedea0SLionel Sambuc jpake_send_step1(bconn, ctx); 2709*ebfedea0SLionel Sambuc jpake_receive_step2(ctx, bconn); 2710*ebfedea0SLionel Sambuc jpake_send_step2(bconn, ctx); 2711*ebfedea0SLionel Sambuc jpake_receive_step3a(ctx, bconn); 2712*ebfedea0SLionel Sambuc jpake_send_step3b(bconn, ctx); 2713*ebfedea0SLionel Sambuc 2714*ebfedea0SLionel Sambuc BIO_puts(out, "JPAKE authentication succeeded, setting PSK\n"); 2715*ebfedea0SLionel Sambuc 2716*ebfedea0SLionel Sambuc psk_key = BN_bn2hex(JPAKE_get_shared_key(ctx)); 2717*ebfedea0SLionel Sambuc 2718*ebfedea0SLionel Sambuc BIO_pop(bconn); 2719*ebfedea0SLionel Sambuc BIO_free(bconn); 2720*ebfedea0SLionel Sambuc 2721*ebfedea0SLionel Sambuc JPAKE_CTX_free(ctx); 2722*ebfedea0SLionel Sambuc } 2723*ebfedea0SLionel Sambuc 2724*ebfedea0SLionel Sambuc #endif 2725*ebfedea0SLionel Sambuc 2726*ebfedea0SLionel Sambuc #if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) 2727*ebfedea0SLionel Sambuc /* next_protos_parse parses a comma separated list of strings into a string 2728*ebfedea0SLionel Sambuc * in a format suitable for passing to SSL_CTX_set_next_protos_advertised. 2729*ebfedea0SLionel Sambuc * outlen: (output) set to the length of the resulting buffer on success. 2730*ebfedea0SLionel Sambuc * err: (maybe NULL) on failure, an error message line is written to this BIO. 2731*ebfedea0SLionel Sambuc * in: a NUL termianted string like "abc,def,ghi" 2732*ebfedea0SLionel Sambuc * 2733*ebfedea0SLionel Sambuc * returns: a malloced buffer or NULL on failure. 2734*ebfedea0SLionel Sambuc */ 2735*ebfedea0SLionel Sambuc unsigned char *next_protos_parse(unsigned short *outlen, const char *in) 2736*ebfedea0SLionel Sambuc { 2737*ebfedea0SLionel Sambuc size_t len; 2738*ebfedea0SLionel Sambuc unsigned char *out; 2739*ebfedea0SLionel Sambuc size_t i, start = 0; 2740*ebfedea0SLionel Sambuc 2741*ebfedea0SLionel Sambuc len = strlen(in); 2742*ebfedea0SLionel Sambuc if (len >= 65535) 2743*ebfedea0SLionel Sambuc return NULL; 2744*ebfedea0SLionel Sambuc 2745*ebfedea0SLionel Sambuc out = OPENSSL_malloc(strlen(in) + 1); 2746*ebfedea0SLionel Sambuc if (!out) 2747*ebfedea0SLionel Sambuc return NULL; 2748*ebfedea0SLionel Sambuc 2749*ebfedea0SLionel Sambuc for (i = 0; i <= len; ++i) 2750*ebfedea0SLionel Sambuc { 2751*ebfedea0SLionel Sambuc if (i == len || in[i] == ',') 2752*ebfedea0SLionel Sambuc { 2753*ebfedea0SLionel Sambuc if (i - start > 255) 2754*ebfedea0SLionel Sambuc { 2755*ebfedea0SLionel Sambuc OPENSSL_free(out); 2756*ebfedea0SLionel Sambuc return NULL; 2757*ebfedea0SLionel Sambuc } 2758*ebfedea0SLionel Sambuc out[start] = i - start; 2759*ebfedea0SLionel Sambuc start = i + 1; 2760*ebfedea0SLionel Sambuc } 2761*ebfedea0SLionel Sambuc else 2762*ebfedea0SLionel Sambuc out[i+1] = in[i]; 2763*ebfedea0SLionel Sambuc } 2764*ebfedea0SLionel Sambuc 2765*ebfedea0SLionel Sambuc *outlen = len + 1; 2766*ebfedea0SLionel Sambuc return out; 2767*ebfedea0SLionel Sambuc } 2768*ebfedea0SLionel Sambuc #endif /* !OPENSSL_NO_TLSEXT && !OPENSSL_NO_NEXTPROTONEG */ 2769*ebfedea0SLionel Sambuc 2770*ebfedea0SLionel Sambuc /* 2771*ebfedea0SLionel Sambuc * Platform-specific sections 2772*ebfedea0SLionel Sambuc */ 2773*ebfedea0SLionel Sambuc #if defined(_WIN32) 2774*ebfedea0SLionel Sambuc # ifdef fileno 2775*ebfedea0SLionel Sambuc # undef fileno 2776*ebfedea0SLionel Sambuc # define fileno(a) (int)_fileno(a) 2777*ebfedea0SLionel Sambuc # endif 2778*ebfedea0SLionel Sambuc 2779*ebfedea0SLionel Sambuc # include <windows.h> 2780*ebfedea0SLionel Sambuc # include <tchar.h> 2781*ebfedea0SLionel Sambuc 2782*ebfedea0SLionel Sambuc static int WIN32_rename(const char *from, const char *to) 2783*ebfedea0SLionel Sambuc { 2784*ebfedea0SLionel Sambuc TCHAR *tfrom=NULL,*tto; 2785*ebfedea0SLionel Sambuc DWORD err; 2786*ebfedea0SLionel Sambuc int ret=0; 2787*ebfedea0SLionel Sambuc 2788*ebfedea0SLionel Sambuc if (sizeof(TCHAR) == 1) 2789*ebfedea0SLionel Sambuc { 2790*ebfedea0SLionel Sambuc tfrom = (TCHAR *)from; 2791*ebfedea0SLionel Sambuc tto = (TCHAR *)to; 2792*ebfedea0SLionel Sambuc } 2793*ebfedea0SLionel Sambuc else /* UNICODE path */ 2794*ebfedea0SLionel Sambuc { 2795*ebfedea0SLionel Sambuc size_t i,flen=strlen(from)+1,tlen=strlen(to)+1; 2796*ebfedea0SLionel Sambuc tfrom = (TCHAR *)malloc(sizeof(TCHAR)*(flen+tlen)); 2797*ebfedea0SLionel Sambuc if (tfrom==NULL) goto err; 2798*ebfedea0SLionel Sambuc tto=tfrom+flen; 2799*ebfedea0SLionel Sambuc #if !defined(_WIN32_WCE) || _WIN32_WCE>=101 2800*ebfedea0SLionel Sambuc if (!MultiByteToWideChar(CP_ACP,0,from,flen,(WCHAR *)tfrom,flen)) 2801*ebfedea0SLionel Sambuc #endif 2802*ebfedea0SLionel Sambuc for (i=0;i<flen;i++) tfrom[i]=(TCHAR)from[i]; 2803*ebfedea0SLionel Sambuc #if !defined(_WIN32_WCE) || _WIN32_WCE>=101 2804*ebfedea0SLionel Sambuc if (!MultiByteToWideChar(CP_ACP,0,to, tlen,(WCHAR *)tto, tlen)) 2805*ebfedea0SLionel Sambuc #endif 2806*ebfedea0SLionel Sambuc for (i=0;i<tlen;i++) tto[i] =(TCHAR)to[i]; 2807*ebfedea0SLionel Sambuc } 2808*ebfedea0SLionel Sambuc 2809*ebfedea0SLionel Sambuc if (MoveFile(tfrom,tto)) goto ok; 2810*ebfedea0SLionel Sambuc err=GetLastError(); 2811*ebfedea0SLionel Sambuc if (err==ERROR_ALREADY_EXISTS || err==ERROR_FILE_EXISTS) 2812*ebfedea0SLionel Sambuc { 2813*ebfedea0SLionel Sambuc if (DeleteFile(tto) && MoveFile(tfrom,tto)) 2814*ebfedea0SLionel Sambuc goto ok; 2815*ebfedea0SLionel Sambuc err=GetLastError(); 2816*ebfedea0SLionel Sambuc } 2817*ebfedea0SLionel Sambuc if (err==ERROR_FILE_NOT_FOUND || err==ERROR_PATH_NOT_FOUND) 2818*ebfedea0SLionel Sambuc errno = ENOENT; 2819*ebfedea0SLionel Sambuc else if (err==ERROR_ACCESS_DENIED) 2820*ebfedea0SLionel Sambuc errno = EACCES; 2821*ebfedea0SLionel Sambuc else 2822*ebfedea0SLionel Sambuc errno = EINVAL; /* we could map more codes... */ 2823*ebfedea0SLionel Sambuc err: 2824*ebfedea0SLionel Sambuc ret=-1; 2825*ebfedea0SLionel Sambuc ok: 2826*ebfedea0SLionel Sambuc if (tfrom!=NULL && tfrom!=(TCHAR *)from) free(tfrom); 2827*ebfedea0SLionel Sambuc return ret; 2828*ebfedea0SLionel Sambuc } 2829*ebfedea0SLionel Sambuc #endif 2830*ebfedea0SLionel Sambuc 2831*ebfedea0SLionel Sambuc /* app_tminterval section */ 2832*ebfedea0SLionel Sambuc #if defined(_WIN32) 2833*ebfedea0SLionel Sambuc double app_tminterval(int stop,int usertime) 2834*ebfedea0SLionel Sambuc { 2835*ebfedea0SLionel Sambuc FILETIME now; 2836*ebfedea0SLionel Sambuc double ret=0; 2837*ebfedea0SLionel Sambuc static ULARGE_INTEGER tmstart; 2838*ebfedea0SLionel Sambuc static int warning=1; 2839*ebfedea0SLionel Sambuc #ifdef _WIN32_WINNT 2840*ebfedea0SLionel Sambuc static HANDLE proc=NULL; 2841*ebfedea0SLionel Sambuc 2842*ebfedea0SLionel Sambuc if (proc==NULL) 2843*ebfedea0SLionel Sambuc { 2844*ebfedea0SLionel Sambuc if (GetVersion() < 0x80000000) 2845*ebfedea0SLionel Sambuc proc = OpenProcess(PROCESS_QUERY_INFORMATION,FALSE, 2846*ebfedea0SLionel Sambuc GetCurrentProcessId()); 2847*ebfedea0SLionel Sambuc if (proc==NULL) proc = (HANDLE)-1; 2848*ebfedea0SLionel Sambuc } 2849*ebfedea0SLionel Sambuc 2850*ebfedea0SLionel Sambuc if (usertime && proc!=(HANDLE)-1) 2851*ebfedea0SLionel Sambuc { 2852*ebfedea0SLionel Sambuc FILETIME junk; 2853*ebfedea0SLionel Sambuc GetProcessTimes(proc,&junk,&junk,&junk,&now); 2854*ebfedea0SLionel Sambuc } 2855*ebfedea0SLionel Sambuc else 2856*ebfedea0SLionel Sambuc #endif 2857*ebfedea0SLionel Sambuc { 2858*ebfedea0SLionel Sambuc SYSTEMTIME systime; 2859*ebfedea0SLionel Sambuc 2860*ebfedea0SLionel Sambuc if (usertime && warning) 2861*ebfedea0SLionel Sambuc { 2862*ebfedea0SLionel Sambuc BIO_printf(bio_err,"To get meaningful results, run " 2863*ebfedea0SLionel Sambuc "this program on idle system.\n"); 2864*ebfedea0SLionel Sambuc warning=0; 2865*ebfedea0SLionel Sambuc } 2866*ebfedea0SLionel Sambuc GetSystemTime(&systime); 2867*ebfedea0SLionel Sambuc SystemTimeToFileTime(&systime,&now); 2868*ebfedea0SLionel Sambuc } 2869*ebfedea0SLionel Sambuc 2870*ebfedea0SLionel Sambuc if (stop==TM_START) 2871*ebfedea0SLionel Sambuc { 2872*ebfedea0SLionel Sambuc tmstart.u.LowPart = now.dwLowDateTime; 2873*ebfedea0SLionel Sambuc tmstart.u.HighPart = now.dwHighDateTime; 2874*ebfedea0SLionel Sambuc } 2875*ebfedea0SLionel Sambuc else { 2876*ebfedea0SLionel Sambuc ULARGE_INTEGER tmstop; 2877*ebfedea0SLionel Sambuc 2878*ebfedea0SLionel Sambuc tmstop.u.LowPart = now.dwLowDateTime; 2879*ebfedea0SLionel Sambuc tmstop.u.HighPart = now.dwHighDateTime; 2880*ebfedea0SLionel Sambuc 2881*ebfedea0SLionel Sambuc ret = (__int64)(tmstop.QuadPart - tmstart.QuadPart)*1e-7; 2882*ebfedea0SLionel Sambuc } 2883*ebfedea0SLionel Sambuc 2884*ebfedea0SLionel Sambuc return (ret); 2885*ebfedea0SLionel Sambuc } 2886*ebfedea0SLionel Sambuc 2887*ebfedea0SLionel Sambuc #elif defined(OPENSSL_SYS_NETWARE) 2888*ebfedea0SLionel Sambuc #include <time.h> 2889*ebfedea0SLionel Sambuc 2890*ebfedea0SLionel Sambuc double app_tminterval(int stop,int usertime) 2891*ebfedea0SLionel Sambuc { 2892*ebfedea0SLionel Sambuc double ret=0; 2893*ebfedea0SLionel Sambuc static clock_t tmstart; 2894*ebfedea0SLionel Sambuc static int warning=1; 2895*ebfedea0SLionel Sambuc 2896*ebfedea0SLionel Sambuc if (usertime && warning) 2897*ebfedea0SLionel Sambuc { 2898*ebfedea0SLionel Sambuc BIO_printf(bio_err,"To get meaningful results, run " 2899*ebfedea0SLionel Sambuc "this program on idle system.\n"); 2900*ebfedea0SLionel Sambuc warning=0; 2901*ebfedea0SLionel Sambuc } 2902*ebfedea0SLionel Sambuc 2903*ebfedea0SLionel Sambuc if (stop==TM_START) tmstart = clock(); 2904*ebfedea0SLionel Sambuc else ret = (clock()-tmstart)/(double)CLOCKS_PER_SEC; 2905*ebfedea0SLionel Sambuc 2906*ebfedea0SLionel Sambuc return (ret); 2907*ebfedea0SLionel Sambuc } 2908*ebfedea0SLionel Sambuc 2909*ebfedea0SLionel Sambuc #elif defined(OPENSSL_SYSTEM_VXWORKS) 2910*ebfedea0SLionel Sambuc #include <time.h> 2911*ebfedea0SLionel Sambuc 2912*ebfedea0SLionel Sambuc double app_tminterval(int stop,int usertime) 2913*ebfedea0SLionel Sambuc { 2914*ebfedea0SLionel Sambuc double ret=0; 2915*ebfedea0SLionel Sambuc #ifdef CLOCK_REALTIME 2916*ebfedea0SLionel Sambuc static struct timespec tmstart; 2917*ebfedea0SLionel Sambuc struct timespec now; 2918*ebfedea0SLionel Sambuc #else 2919*ebfedea0SLionel Sambuc static unsigned long tmstart; 2920*ebfedea0SLionel Sambuc unsigned long now; 2921*ebfedea0SLionel Sambuc #endif 2922*ebfedea0SLionel Sambuc static int warning=1; 2923*ebfedea0SLionel Sambuc 2924*ebfedea0SLionel Sambuc if (usertime && warning) 2925*ebfedea0SLionel Sambuc { 2926*ebfedea0SLionel Sambuc BIO_printf(bio_err,"To get meaningful results, run " 2927*ebfedea0SLionel Sambuc "this program on idle system.\n"); 2928*ebfedea0SLionel Sambuc warning=0; 2929*ebfedea0SLionel Sambuc } 2930*ebfedea0SLionel Sambuc 2931*ebfedea0SLionel Sambuc #ifdef CLOCK_REALTIME 2932*ebfedea0SLionel Sambuc clock_gettime(CLOCK_REALTIME,&now); 2933*ebfedea0SLionel Sambuc if (stop==TM_START) tmstart = now; 2934*ebfedea0SLionel Sambuc else ret = ( (now.tv_sec+now.tv_nsec*1e-9) 2935*ebfedea0SLionel Sambuc - (tmstart.tv_sec+tmstart.tv_nsec*1e-9) ); 2936*ebfedea0SLionel Sambuc #else 2937*ebfedea0SLionel Sambuc now = tickGet(); 2938*ebfedea0SLionel Sambuc if (stop==TM_START) tmstart = now; 2939*ebfedea0SLionel Sambuc else ret = (now - tmstart)/(double)sysClkRateGet(); 2940*ebfedea0SLionel Sambuc #endif 2941*ebfedea0SLionel Sambuc return (ret); 2942*ebfedea0SLionel Sambuc } 2943*ebfedea0SLionel Sambuc 2944*ebfedea0SLionel Sambuc #elif defined(OPENSSL_SYSTEM_VMS) 2945*ebfedea0SLionel Sambuc #include <time.h> 2946*ebfedea0SLionel Sambuc #include <times.h> 2947*ebfedea0SLionel Sambuc 2948*ebfedea0SLionel Sambuc double app_tminterval(int stop,int usertime) 2949*ebfedea0SLionel Sambuc { 2950*ebfedea0SLionel Sambuc static clock_t tmstart; 2951*ebfedea0SLionel Sambuc double ret = 0; 2952*ebfedea0SLionel Sambuc clock_t now; 2953*ebfedea0SLionel Sambuc #ifdef __TMS 2954*ebfedea0SLionel Sambuc struct tms rus; 2955*ebfedea0SLionel Sambuc 2956*ebfedea0SLionel Sambuc now = times(&rus); 2957*ebfedea0SLionel Sambuc if (usertime) now = rus.tms_utime; 2958*ebfedea0SLionel Sambuc #else 2959*ebfedea0SLionel Sambuc if (usertime) 2960*ebfedea0SLionel Sambuc now = clock(); /* sum of user and kernel times */ 2961*ebfedea0SLionel Sambuc else { 2962*ebfedea0SLionel Sambuc struct timeval tv; 2963*ebfedea0SLionel Sambuc gettimeofday(&tv,NULL); 2964*ebfedea0SLionel Sambuc now = (clock_t)( 2965*ebfedea0SLionel Sambuc (unsigned long long)tv.tv_sec*CLK_TCK + 2966*ebfedea0SLionel Sambuc (unsigned long long)tv.tv_usec*(1000000/CLK_TCK) 2967*ebfedea0SLionel Sambuc ); 2968*ebfedea0SLionel Sambuc } 2969*ebfedea0SLionel Sambuc #endif 2970*ebfedea0SLionel Sambuc if (stop==TM_START) tmstart = now; 2971*ebfedea0SLionel Sambuc else ret = (now - tmstart)/(double)(CLK_TCK); 2972*ebfedea0SLionel Sambuc 2973*ebfedea0SLionel Sambuc return (ret); 2974*ebfedea0SLionel Sambuc } 2975*ebfedea0SLionel Sambuc 2976*ebfedea0SLionel Sambuc #elif defined(_SC_CLK_TCK) /* by means of unistd.h */ 2977*ebfedea0SLionel Sambuc #include <sys/times.h> 2978*ebfedea0SLionel Sambuc 2979*ebfedea0SLionel Sambuc double app_tminterval(int stop,int usertime) 2980*ebfedea0SLionel Sambuc { 2981*ebfedea0SLionel Sambuc double ret = 0; 2982*ebfedea0SLionel Sambuc struct tms rus; 2983*ebfedea0SLionel Sambuc clock_t now = times(&rus); 2984*ebfedea0SLionel Sambuc static clock_t tmstart; 2985*ebfedea0SLionel Sambuc 2986*ebfedea0SLionel Sambuc if (usertime) now = rus.tms_utime; 2987*ebfedea0SLionel Sambuc 2988*ebfedea0SLionel Sambuc if (stop==TM_START) tmstart = now; 2989*ebfedea0SLionel Sambuc else 2990*ebfedea0SLionel Sambuc { 2991*ebfedea0SLionel Sambuc long int tck = sysconf(_SC_CLK_TCK); 2992*ebfedea0SLionel Sambuc ret = (now - tmstart)/(double)tck; 2993*ebfedea0SLionel Sambuc } 2994*ebfedea0SLionel Sambuc 2995*ebfedea0SLionel Sambuc return (ret); 2996*ebfedea0SLionel Sambuc } 2997*ebfedea0SLionel Sambuc 2998*ebfedea0SLionel Sambuc #else 2999*ebfedea0SLionel Sambuc #include <sys/time.h> 3000*ebfedea0SLionel Sambuc #include <sys/resource.h> 3001*ebfedea0SLionel Sambuc 3002*ebfedea0SLionel Sambuc double app_tminterval(int stop,int usertime) 3003*ebfedea0SLionel Sambuc { 3004*ebfedea0SLionel Sambuc double ret = 0; 3005*ebfedea0SLionel Sambuc struct rusage rus; 3006*ebfedea0SLionel Sambuc struct timeval now; 3007*ebfedea0SLionel Sambuc static struct timeval tmstart; 3008*ebfedea0SLionel Sambuc 3009*ebfedea0SLionel Sambuc if (usertime) getrusage(RUSAGE_SELF,&rus), now = rus.ru_utime; 3010*ebfedea0SLionel Sambuc else gettimeofday(&now,NULL); 3011*ebfedea0SLionel Sambuc 3012*ebfedea0SLionel Sambuc if (stop==TM_START) tmstart = now; 3013*ebfedea0SLionel Sambuc else ret = ( (now.tv_sec+now.tv_usec*1e-6) 3014*ebfedea0SLionel Sambuc - (tmstart.tv_sec+tmstart.tv_usec*1e-6) ); 3015*ebfedea0SLionel Sambuc 3016*ebfedea0SLionel Sambuc return ret; 3017*ebfedea0SLionel Sambuc } 3018*ebfedea0SLionel Sambuc #endif 3019*ebfedea0SLionel Sambuc 3020*ebfedea0SLionel Sambuc /* app_isdir section */ 3021*ebfedea0SLionel Sambuc #ifdef _WIN32 3022*ebfedea0SLionel Sambuc int app_isdir(const char *name) 3023*ebfedea0SLionel Sambuc { 3024*ebfedea0SLionel Sambuc HANDLE hList; 3025*ebfedea0SLionel Sambuc WIN32_FIND_DATA FileData; 3026*ebfedea0SLionel Sambuc #if defined(UNICODE) || defined(_UNICODE) 3027*ebfedea0SLionel Sambuc size_t i, len_0 = strlen(name)+1; 3028*ebfedea0SLionel Sambuc 3029*ebfedea0SLionel Sambuc if (len_0 > sizeof(FileData.cFileName)/sizeof(FileData.cFileName[0])) 3030*ebfedea0SLionel Sambuc return -1; 3031*ebfedea0SLionel Sambuc 3032*ebfedea0SLionel Sambuc #if !defined(_WIN32_WCE) || _WIN32_WCE>=101 3033*ebfedea0SLionel Sambuc if (!MultiByteToWideChar(CP_ACP,0,name,len_0,FileData.cFileName,len_0)) 3034*ebfedea0SLionel Sambuc #endif 3035*ebfedea0SLionel Sambuc for (i=0;i<len_0;i++) 3036*ebfedea0SLionel Sambuc FileData.cFileName[i] = (WCHAR)name[i]; 3037*ebfedea0SLionel Sambuc 3038*ebfedea0SLionel Sambuc hList = FindFirstFile(FileData.cFileName,&FileData); 3039*ebfedea0SLionel Sambuc #else 3040*ebfedea0SLionel Sambuc hList = FindFirstFile(name,&FileData); 3041*ebfedea0SLionel Sambuc #endif 3042*ebfedea0SLionel Sambuc if (hList == INVALID_HANDLE_VALUE) return -1; 3043*ebfedea0SLionel Sambuc FindClose(hList); 3044*ebfedea0SLionel Sambuc return ((FileData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)!=0); 3045*ebfedea0SLionel Sambuc } 3046*ebfedea0SLionel Sambuc #else 3047*ebfedea0SLionel Sambuc #include <sys/stat.h> 3048*ebfedea0SLionel Sambuc #ifndef S_ISDIR 3049*ebfedea0SLionel Sambuc # if defined(_S_IFMT) && defined(_S_IFDIR) 3050*ebfedea0SLionel Sambuc # define S_ISDIR(a) (((a) & _S_IFMT) == _S_IFDIR) 3051*ebfedea0SLionel Sambuc # else 3052*ebfedea0SLionel Sambuc # define S_ISDIR(a) (((a) & S_IFMT) == S_IFDIR) 3053*ebfedea0SLionel Sambuc # endif 3054*ebfedea0SLionel Sambuc #endif 3055*ebfedea0SLionel Sambuc 3056*ebfedea0SLionel Sambuc int app_isdir(const char *name) 3057*ebfedea0SLionel Sambuc { 3058*ebfedea0SLionel Sambuc #if defined(S_ISDIR) 3059*ebfedea0SLionel Sambuc struct stat st; 3060*ebfedea0SLionel Sambuc 3061*ebfedea0SLionel Sambuc if (stat(name,&st)==0) return S_ISDIR(st.st_mode); 3062*ebfedea0SLionel Sambuc else return -1; 3063*ebfedea0SLionel Sambuc #else 3064*ebfedea0SLionel Sambuc return -1; 3065*ebfedea0SLionel Sambuc #endif 3066*ebfedea0SLionel Sambuc } 3067*ebfedea0SLionel Sambuc #endif 3068*ebfedea0SLionel Sambuc 3069*ebfedea0SLionel Sambuc /* raw_read|write section */ 3070*ebfedea0SLionel Sambuc #if defined(_WIN32) && defined(STD_INPUT_HANDLE) 3071*ebfedea0SLionel Sambuc int raw_read_stdin(void *buf,int siz) 3072*ebfedea0SLionel Sambuc { 3073*ebfedea0SLionel Sambuc DWORD n; 3074*ebfedea0SLionel Sambuc if (ReadFile(GetStdHandle(STD_INPUT_HANDLE),buf,siz,&n,NULL)) 3075*ebfedea0SLionel Sambuc return (n); 3076*ebfedea0SLionel Sambuc else return (-1); 3077*ebfedea0SLionel Sambuc } 3078*ebfedea0SLionel Sambuc #else 3079*ebfedea0SLionel Sambuc int raw_read_stdin(void *buf,int siz) 3080*ebfedea0SLionel Sambuc { return read(fileno(stdin),buf,siz); } 3081*ebfedea0SLionel Sambuc #endif 3082*ebfedea0SLionel Sambuc 3083*ebfedea0SLionel Sambuc #if defined(_WIN32) && defined(STD_OUTPUT_HANDLE) 3084*ebfedea0SLionel Sambuc int raw_write_stdout(const void *buf,int siz) 3085*ebfedea0SLionel Sambuc { 3086*ebfedea0SLionel Sambuc DWORD n; 3087*ebfedea0SLionel Sambuc if (WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),buf,siz,&n,NULL)) 3088*ebfedea0SLionel Sambuc return (n); 3089*ebfedea0SLionel Sambuc else return (-1); 3090*ebfedea0SLionel Sambuc } 3091*ebfedea0SLionel Sambuc #else 3092*ebfedea0SLionel Sambuc int raw_write_stdout(const void *buf,int siz) 3093*ebfedea0SLionel Sambuc { return write(fileno(stdout),buf,siz); } 3094*ebfedea0SLionel Sambuc #endif 3095