00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00032 #ifdef HAVE_OPENSSL
00033 #include <stdio.h>
00034 #include <string.h>
00035 #include <assert.h>
00036
00037 #include <openssl/ssl.h>
00038 #include <openssl/pkcs12.h>
00039 #include <openssl/evp.h>
00040 #include <openssl/err.h>
00041
00042 #include <eurephia_nullsafe.h>
00043 #include <certinfo.h>
00044
00045 #include "get_console_input.h"
00046 #define _PARSE_CERTFICIATE_FILES_C
00047 #include "parse_certificate_files.h"
00048
00049
00059 char *ExtractCertInfo(const char *module, X509 *cert, const char *fieldname) {
00060 unsigned char *buf = (unsigned char *)1;
00061 char resbuf[2050];
00062 X509_NAME *name = NULL;
00063 X509_NAME_ENTRY *namentry = NULL;
00064 ASN1_STRING *asn1 = NULL;
00065 int nid, tmp = -1, pos = -1;
00066
00067
00068
00069
00070
00071 memset(resbuf, 0, 2050);
00072
00073 nid = OBJ_txt2nid(fieldname);
00074 name = X509_get_subject_name(cert);
00075
00076 do {
00077 pos = tmp;
00078 tmp = X509_NAME_get_index_by_NID(name, nid, pos);
00079 } while ( tmp > -1 );
00080
00081 if( pos == -1 ) {
00082 fprintf(stderr, "%s: Field '%s' not found\n", module, fieldname);
00083 return 0;
00084 }
00085
00086 if( !(namentry = X509_NAME_get_entry(name, pos)) ) {
00087 fprintf(stderr, "%s: Failed to extract name entry from field '%s'\n", module, fieldname);
00088 return 0;
00089 }
00090
00091 if( !(asn1 = X509_NAME_ENTRY_get_data(namentry)) ) {
00092 fprintf(stderr, "%s: Failed to extract data from name entry field '%s'\n", module, fieldname);
00093 return 0;
00094 }
00095
00096 if( ASN1_STRING_to_UTF8(&buf, asn1) <= 0 ) {
00097 fprintf(stderr, "%s: Failed to convert ASN1 string to UTF-8 for '%s'\n", module, fieldname);
00098 return 0;
00099 }
00100
00101 snprintf(resbuf, 2048, "%s%c", buf, '\0');
00102 OPENSSL_free(buf);
00103
00104 return strdup_nullsafe(resbuf);
00105 }
00106
00107
00118 certinfo *_Cert_ParseFile(const char *module, const char *certfile, int certfile_format) {
00119 BIO *bio_err = NULL;
00120 PKCS12 *p12 = NULL;
00121 EVP_PKEY *pkey = NULL;
00122 X509 *cert = NULL;
00123 FILE *fp;
00124 certinfo *ret = NULL;
00125
00126
00127 unsigned char md_sha1[EVP_MAX_MD_SIZE];
00128 unsigned int mdlen;
00129
00130 if( !bio_err ) {
00131 SSL_library_init();
00132 SSL_load_error_strings();
00133 bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
00134 }
00135
00136
00137 switch( certfile_format ) {
00138 case CERTFILE_PEM:
00139 fp = fopen(certfile, "r");
00140 if( !(cert = PEM_read_X509(fp, NULL, NULL, NULL)) ) {
00141 fprintf(stderr, "%s: Failed to open certificate file\n", module);
00142 return NULL;
00143 }
00144 fclose(fp);
00145 break;
00146
00147 case CERTFILE_PKCS12:
00148 fp = fopen(certfile, "r");
00149 p12 = d2i_PKCS12_fp(fp, NULL);
00150 fclose(fp);
00151 if( p12 == NULL ) {
00152 fprintf(stderr, "%s: Could not open PKCS#12 file\n", module);
00153 return NULL;
00154 }
00155 OpenSSL_add_all_ciphers();
00156
00157
00158 if( !PKCS12_parse(p12, "", &pkey, &cert, NULL) ) {
00159 char pwd[130];
00160
00161
00162 memset(&pwd, 0, 130);
00163 if( get_console_input(pwd, 128, "PKCS12 password:", 1) < 0 ) {
00164 fprintf(stderr, "Could not retrieve password\n");
00165 }
00166 if( !PKCS12_parse(p12, pwd, &pkey, &cert, NULL) ) {
00167 PKCS12_free(p12); p12 = NULL;
00168 fprintf(stderr,
00169 "%s: Could not open PKCS#12 file - wrong password\n", module);
00170 fprintf(stderr,
00171 "%s: %s\n", module, ERR_error_string(ERR_get_error(), NULL));
00172 BIO_free(bio_err);
00173 return NULL;
00174 }
00175 }
00176 EVP_PKEY_free(pkey); pkey = NULL;
00177 PKCS12_free(p12); p12 = NULL;
00178 break;
00179
00180 default:
00181 fprintf(stderr, "%s: Unknown certificate file format\n", module);
00182 return NULL;
00183 }
00184
00185 ret = (certinfo *) malloc_nullsafe(NULL, sizeof(certinfo)+2);
00186 assert( ret != NULL );
00187
00188 ret->digest = (char *) malloc_nullsafe(NULL, 66);
00189 assert(ret != NULL);
00190
00191
00192
00193 if (X509_digest(cert, EVP_sha1(), md_sha1, &mdlen) && mdlen > 0) {
00194 static const char hexcodes[] = "0123456789ABCDEF";
00195 int j;
00196
00197 for (j = 0; j < (int) mdlen; j++) {
00198 ret->digest[j * 3] = hexcodes[(md_sha1[j] & 0xf0) >> 4U];
00199 ret->digest[(j * 3) + 1] = hexcodes[(md_sha1[j] & 0x0f)];
00200 if (j + 1 != (int) mdlen) {
00201 ret->digest[(j * 3) + 2] = ':';
00202 } else {
00203 ret->digest[(j * 3) + 2] = '\0';
00204 }
00205 }
00206 }
00207
00208
00209 ret->common_name = ExtractCertInfo(module, cert, "CN");
00210 ret->org = ExtractCertInfo(module, cert, "O");
00211 ret->email = ExtractCertInfo(module, cert, "emailAddress");
00212
00213 X509_free(cert);
00214 BIO_free(bio_err);
00215
00216 return ret;
00217 }
00218 #endif