1/* 2 * Copyright (C) 1997-2000 Sensus Consulting Ltd. 3 * Matt Newman <matt@sensus.org> 4 * 5 * $Header: /cvsroot/tls/tls/tlsX509.c,v 1.5 2004/06/29 10:58:08 patthoyts Exp $ 6 */ 7#include "tlsInt.h" 8 9/* 10 * Ensure these are not macros - known to be defined on Win32 11 */ 12#ifdef min 13#undef min 14#endif 15 16#ifdef max 17#undef max 18#endif 19 20static int min(int a, int b) 21{ 22 return (a < b) ? a : b; 23} 24 25static int max(int a, int b) 26{ 27 return (a > b) ? a : b; 28} 29 30/* 31 * ASN1_UTCTIME_tostr -- 32 */ 33static char * 34ASN1_UTCTIME_tostr(ASN1_UTCTIME *tm) 35{ 36 static char bp[128]; 37 char *v; 38 int gmt=0; 39 static char *mon[12]={ 40 "Jan","Feb","Mar","Apr","May","Jun", 41 "Jul","Aug","Sep","Oct","Nov","Dec"}; 42 int i; 43 int y=0,M=0,d=0,h=0,m=0,s=0; 44 45 i=tm->length; 46 v=(char *)tm->data; 47 48 if (i < 10) goto err; 49 if (v[i-1] == 'Z') gmt=1; 50 for (i=0; i<10; i++) 51 if ((v[i] > '9') || (v[i] < '0')) goto err; 52 y= (v[0]-'0')*10+(v[1]-'0'); 53 if (y < 70) y+=100; 54 M= (v[2]-'0')*10+(v[3]-'0'); 55 if ((M > 12) || (M < 1)) goto err; 56 d= (v[4]-'0')*10+(v[5]-'0'); 57 h= (v[6]-'0')*10+(v[7]-'0'); 58 m= (v[8]-'0')*10+(v[9]-'0'); 59 if ( (v[10] >= '0') && (v[10] <= '9') && 60 (v[11] >= '0') && (v[11] <= '9')) 61 s= (v[10]-'0')*10+(v[11]-'0'); 62 63 sprintf(bp,"%s %2d %02d:%02d:%02d %d%s", 64 mon[M-1],d,h,m,s,y+1900,(gmt)?" GMT":""); 65 return bp; 66 err: 67 return "Bad time value"; 68} 69 70/* 71 *------------------------------------------------------* 72 * 73 * Tls_NewX509Obj -- 74 * 75 * ------------------------------------------------* 76 * Converts a X509 certificate into a Tcl_Obj 77 * ------------------------------------------------* 78 * 79 * Sideeffects: 80 * None 81 * 82 * Result: 83 * A Tcl List Object representing the provided 84 * X509 certificate. 85 * 86 *------------------------------------------------------* 87 */ 88 89Tcl_Obj* 90Tls_NewX509Obj( interp, cert) 91 Tcl_Interp *interp; 92 X509 *cert; 93{ 94 Tcl_Obj *certPtr = Tcl_NewListObj( 0, NULL); 95 BIO *bio; 96 int n; 97 unsigned long flags; 98 char subject[BUFSIZ]; 99 char issuer[BUFSIZ]; 100 char serial[BUFSIZ]; 101 char notBefore[BUFSIZ]; 102 char notAfter[BUFSIZ]; 103#ifndef NO_SSL_SHA 104 int shai; 105 char sha_hash[SHA_DIGEST_LENGTH*2]; 106 const char *shachars="0123456789ABCDEF"; 107#endif 108 109 if ((bio = BIO_new(BIO_s_mem())) == NULL) { 110 subject[0] = 0; 111 issuer[0] = 0; 112 serial[0] = 0; 113 } else { 114 flags = XN_FLAG_RFC2253 | ASN1_STRFLGS_UTF8_CONVERT; 115 flags &= ~ASN1_STRFLGS_ESC_MSB; 116 117 X509_NAME_print_ex(bio, X509_get_subject_name(cert), 0, flags); 118 n = BIO_read(bio, subject, min(BIO_pending(bio), BUFSIZ - 1)); 119 n = max(n, 0); 120 subject[n] = 0; 121 BIO_flush(bio); 122 123 X509_NAME_print_ex(bio, X509_get_issuer_name(cert), 0, flags); 124 n = BIO_read(bio, issuer, min(BIO_pending(bio), BUFSIZ - 1)); 125 n = max(n, 0); 126 issuer[n] = 0; 127 BIO_flush(bio); 128 129 i2a_ASN1_INTEGER(bio, X509_get_serialNumber(cert)); 130 n = BIO_read(bio, serial, min(BIO_pending(bio), BUFSIZ - 1)); 131 n = max(n, 0); 132 serial[n] = 0; 133 BIO_flush(bio); 134 135 BIO_free(bio); 136 } 137 138 strcpy( notBefore, ASN1_UTCTIME_tostr( X509_get_notBefore(cert) )); 139 strcpy( notAfter, ASN1_UTCTIME_tostr( X509_get_notAfter(cert) )); 140 141#ifndef NO_SSL_SHA 142 for (shai=0;shai<SHA_DIGEST_LENGTH;shai++) 143 { 144 sha_hash[shai * 2]=shachars[(cert->sha1_hash[shai] & 0xF0) >> 4]; 145 sha_hash[shai * 2 + 1]=shachars[(cert->sha1_hash[shai] & 0x0F)]; 146 } 147 Tcl_ListObjAppendElement( interp, certPtr, 148 Tcl_NewStringObj( "sha1_hash", -1) ); 149 Tcl_ListObjAppendElement( interp, certPtr, 150 Tcl_NewStringObj( sha_hash, SHA_DIGEST_LENGTH*2) ); 151 152#endif 153 Tcl_ListObjAppendElement( interp, certPtr, 154 Tcl_NewStringObj( "subject", -1) ); 155 Tcl_ListObjAppendElement( interp, certPtr, 156 Tcl_NewStringObj( subject, -1) ); 157 158 Tcl_ListObjAppendElement( interp, certPtr, 159 Tcl_NewStringObj( "issuer", -1) ); 160 Tcl_ListObjAppendElement( interp, certPtr, 161 Tcl_NewStringObj( issuer, -1) ); 162 163 Tcl_ListObjAppendElement( interp, certPtr, 164 Tcl_NewStringObj( "notBefore", -1) ); 165 Tcl_ListObjAppendElement( interp, certPtr, 166 Tcl_NewStringObj( notBefore, -1) ); 167 168 Tcl_ListObjAppendElement( interp, certPtr, 169 Tcl_NewStringObj( "notAfter", -1) ); 170 Tcl_ListObjAppendElement( interp, certPtr, 171 Tcl_NewStringObj( notAfter, -1) ); 172 173 Tcl_ListObjAppendElement( interp, certPtr, 174 Tcl_NewStringObj( "serial", -1) ); 175 Tcl_ListObjAppendElement( interp, certPtr, 176 Tcl_NewStringObj( serial, -1) ); 177 178 return certPtr; 179} 180