__gaa_helpsingle(0, "load-ca-privkey", "FILE ", "Certificate authority's private key file to use.");
__gaa_helpsingle(0, "load-ca-certificate", "FILE ", "Certificate authority's certificate file to use.");
__gaa_helpsingle('i', "certificate-info", "", "Print information on a certificate.");
+ __gaa_helpsingle(0, "p12-info", "", "Print information on a PKCS #12 structure.");
__gaa_helpsingle('k', "key-info", "", "Print information on a private key.");
__gaa_helpsingle(0, "to-p12", "", "Generate a PKCS #12 structure.");
__gaa_helpsingle('8', "pkcs8", "", "Use PKCS #8 format for private keys.");
__gaa_helpsingle(0, "inder", "", "Use DER format for input certificates and private keys.");
+ __gaa_helpsingle(0, "outder", "", "Use DER format for output certificates and private keys.");
__gaa_helpsingle(0, "bits", "BITS ", "specify the number of bits for key generation.");
__gaa_helpsingle(0, "outfile", "FILE ", "Output file.");
__gaa_helpsingle(0, "infile", "FILE ", "Output file.");
struct _gaainfo
{
-#line 52 "certtool.gaa"
+#line 57 "certtool.gaa"
int debug;
-#line 49 "certtool.gaa"
+#line 54 "certtool.gaa"
char *infile;
-#line 46 "certtool.gaa"
+#line 51 "certtool.gaa"
char *outfile;
-#line 43 "certtool.gaa"
+#line 48 "certtool.gaa"
int bits;
-#line 40 "certtool.gaa"
+#line 45 "certtool.gaa"
+ int outcert_format;
+#line 42 "certtool.gaa"
int incert_format;
-#line 37 "certtool.gaa"
+#line 39 "certtool.gaa"
int pkcs8;
#line 28 "certtool.gaa"
char *ca;
#define GAA_MULTIPLE_OPTION 3
#define GAA_REST 0
-#define GAA_NB_OPTION 22
+#define GAA_NB_OPTION 24
#define GAAOPTID_version 1
#define GAAOPTID_help 2
#define GAAOPTID_debug 3
#define GAAOPTID_infile 4
#define GAAOPTID_outfile 5
#define GAAOPTID_bits 6
-#define GAAOPTID_inder 7
-#define GAAOPTID_pkcs8 8
-#define GAAOPTID_to_p12 9
-#define GAAOPTID_key_info 10
-#define GAAOPTID_certificate_info 11
-#define GAAOPTID_load_ca_certificate 12
-#define GAAOPTID_load_ca_privkey 13
-#define GAAOPTID_load_certificate 14
-#define GAAOPTID_load_request 15
-#define GAAOPTID_load_privkey 16
-#define GAAOPTID_verify_chain 17
-#define GAAOPTID_generate_request 18
-#define GAAOPTID_generate_privkey 19
-#define GAAOPTID_update_certificate 20
-#define GAAOPTID_generate_certificate 21
-#define GAAOPTID_generate_self_signed 22
+#define GAAOPTID_outder 7
+#define GAAOPTID_inder 8
+#define GAAOPTID_pkcs8 9
+#define GAAOPTID_to_p12 10
+#define GAAOPTID_key_info 11
+#define GAAOPTID_p12_info 12
+#define GAAOPTID_certificate_info 13
+#define GAAOPTID_load_ca_certificate 14
+#define GAAOPTID_load_ca_privkey 15
+#define GAAOPTID_load_certificate 16
+#define GAAOPTID_load_request 17
+#define GAAOPTID_load_privkey 18
+#define GAAOPTID_verify_chain 19
+#define GAAOPTID_generate_request 20
+#define GAAOPTID_generate_privkey 21
+#define GAAOPTID_update_certificate 22
+#define GAAOPTID_generate_certificate 23
+#define GAAOPTID_generate_self_signed 24
#line 168 "gaa.skel"
#line 375 "gaa.skel"
GAA_CHECK1STR("v", GAAOPTID_version);
GAA_CHECK1STR("h", GAAOPTID_help);
+ GAA_CHECK1STR("", GAAOPTID_outder);
GAA_CHECK1STR("", GAAOPTID_inder);
GAA_CHECK1STR("8", GAAOPTID_pkcs8);
GAA_CHECK1STR("", GAAOPTID_to_p12);
GAA_CHECK1STR("k", GAAOPTID_key_info);
+ GAA_CHECK1STR("", GAAOPTID_p12_info);
GAA_CHECK1STR("i", GAAOPTID_certificate_info);
GAA_CHECK1STR("e", GAAOPTID_verify_chain);
GAA_CHECK1STR("q", GAAOPTID_generate_request);
GAA_CHECKSTR("infile", GAAOPTID_infile);
GAA_CHECKSTR("outfile", GAAOPTID_outfile);
GAA_CHECKSTR("bits", GAAOPTID_bits);
+ GAA_CHECKSTR("outder", GAAOPTID_outder);
GAA_CHECKSTR("inder", GAAOPTID_inder);
GAA_CHECKSTR("pkcs8", GAAOPTID_pkcs8);
GAA_CHECKSTR("to-p12", GAAOPTID_to_p12);
GAA_CHECKSTR("key-info", GAAOPTID_key_info);
+ GAA_CHECKSTR("p12-info", GAAOPTID_p12_info);
GAA_CHECKSTR("certificate-info", GAAOPTID_certificate_info);
GAA_CHECKSTR("load-ca-certificate", GAAOPTID_load_ca_certificate);
GAA_CHECKSTR("load-ca-privkey", GAAOPTID_load_ca_privkey);
{
case GAAOPTID_version:
OK = 0;
-#line 57 "certtool.gaa"
+#line 62 "certtool.gaa"
{ certtool_version(); exit(0); ;};
return GAA_OK;
break;
case GAAOPTID_help:
OK = 0;
-#line 55 "certtool.gaa"
+#line 60 "certtool.gaa"
{ gaa_help(); exit(0); ;};
return GAA_OK;
GAA_TESTMOREARGS;
GAA_FILL(GAATMP_debug.arg1, gaa_getint, GAATMP_debug.size1);
gaa_index++;
-#line 53 "certtool.gaa"
+#line 58 "certtool.gaa"
{ gaaval->debug = GAATMP_debug.arg1 ;};
return GAA_OK;
GAA_TESTMOREARGS;
GAA_FILL(GAATMP_infile.arg1, gaa_getstr, GAATMP_infile.size1);
gaa_index++;
-#line 50 "certtool.gaa"
+#line 55 "certtool.gaa"
{ gaaval->infile = GAATMP_infile.arg1 ;};
return GAA_OK;
GAA_TESTMOREARGS;
GAA_FILL(GAATMP_outfile.arg1, gaa_getstr, GAATMP_outfile.size1);
gaa_index++;
-#line 47 "certtool.gaa"
+#line 52 "certtool.gaa"
{ gaaval->outfile = GAATMP_outfile.arg1 ;};
return GAA_OK;
GAA_TESTMOREARGS;
GAA_FILL(GAATMP_bits.arg1, gaa_getint, GAATMP_bits.size1);
gaa_index++;
-#line 44 "certtool.gaa"
+#line 49 "certtool.gaa"
{ gaaval->bits = GAATMP_bits.arg1 ;};
+ return GAA_OK;
+ break;
+ case GAAOPTID_outder:
+ OK = 0;
+#line 46 "certtool.gaa"
+{ gaaval->outcert_format=1 ;};
+
return GAA_OK;
break;
case GAAOPTID_inder:
OK = 0;
-#line 41 "certtool.gaa"
+#line 43 "certtool.gaa"
{ gaaval->incert_format=1 ;};
return GAA_OK;
break;
case GAAOPTID_pkcs8:
OK = 0;
-#line 38 "certtool.gaa"
+#line 40 "certtool.gaa"
{ gaaval->pkcs8=1 ;};
return GAA_OK;
break;
case GAAOPTID_to_p12:
OK = 0;
-#line 35 "certtool.gaa"
+#line 37 "certtool.gaa"
{ gaaval->action = 8; ;};
return GAA_OK;
break;
case GAAOPTID_key_info:
OK = 0;
-#line 33 "certtool.gaa"
+#line 35 "certtool.gaa"
{ gaaval->action = 6; ;};
+ return GAA_OK;
+ break;
+ case GAAOPTID_p12_info:
+ OK = 0;
+#line 33 "certtool.gaa"
+{ gaaval->action = 9; ;};
+
return GAA_OK;
break;
case GAAOPTID_certificate_info:
if(inited == 0)
{
-#line 59 "certtool.gaa"
+#line 64 "certtool.gaa"
{ gaaval->bits = 1024; gaaval->pkcs8 = 0; gaaval->privkey = NULL; gaaval->ca=NULL; gaaval->ca_privkey = NULL;
gaaval->debug=1; gaaval->request = NULL; gaaval->infile = NULL; gaaval->outfile = NULL; gaaval->cert = NULL;
- gaaval->incert_format = 0; ;};
+ gaaval->incert_format = 0; gaaval->outcert_format = 0; ;};
}
inited = 1;
#include <gnutls/pkcs12.h>
#include <unistd.h>
+void pkcs12_info( void);
void generate_pkcs12( void);
void verify_chain(void);
gnutls_x509_privkey load_private_key(void);
FILE* outfile;
FILE* infile;
int in_cert_format;
-int out_cert_format = GNUTLS_X509_FMT_PEM;
+int out_cert_format;
static unsigned char buffer[50*1024];
static const int buffer_size = sizeof(buffer);
if (!info.pkcs8) {
size = sizeof(buffer);
- ret = gnutls_x509_privkey_export( key, out_cert_format, buffer, &size);
+ ret = gnutls_x509_privkey_export( key, out_cert_format, buffer, &size);
if (ret < 0) {
fprintf(stderr, "privkey_export: %s\n", gnutls_strerror(ret));
exit(1);
}
}
- fprintf(outfile,"Private key: \n%s\n", buffer);
+ fwrite(buffer, 1, size, outfile);
}
void generate_private_key( void)
crq = load_request();
-
+
if (crq == NULL) {
fprintf(stderr, "Please enter the details of the certificate's distinguished name. "
"Just press enter to ignore a field.\n");
- key = generate_private_key_int();
+ key = load_private_key();
read_crt_set( crt, "Country name (2 chars): ", GNUTLS_OID_X520_COUNTRY_NAME);
read_crt_set( crt, "Organization name: ", GNUTLS_OID_X520_ORGANIZATION_NAME);
fprintf(stderr, "serial: %s\n", gnutls_strerror(result));
exit(1);
}
-
+
return crt;
}
exit(1);
}
- print_private_key( key);
-
size = sizeof(buffer);
result = gnutls_x509_crt_export( crt, out_cert_format, buffer, &size);
if (result < 0) {
exit(1);
}
- fprintf(outfile, "Certificate: \n%s", buffer);
-
+ fwrite( buffer, 1, size, outfile);
gnutls_x509_crt_deinit(crt);
gnutls_x509_privkey_deinit(key);
- fclose(outfile);
}
void generate_signed_certificate( void)
exit(1);
}
- print_private_key( key);
-
size = sizeof(buffer);
result = gnutls_x509_crt_export( crt, out_cert_format, buffer, &size);
if (result < 0) {
exit(1);
}
- fprintf(outfile, "Certificate: \n%s", buffer);
+ fwrite( buffer, 1, size, outfile);
gnutls_x509_crt_deinit(crt);
gnutls_x509_privkey_deinit(key);
exit(1);
}
- fprintf(outfile, "Certificate: \n%s", buffer);
+ fwrite( buffer, 1, size, outfile);
gnutls_x509_crt_deinit(crt);
}
if (info.incert_format) in_cert_format = GNUTLS_X509_FMT_DER;
else in_cert_format = GNUTLS_X509_FMT_PEM;
+ if (info.outcert_format) out_cert_format = GNUTLS_X509_FMT_DER;
+ else out_cert_format = GNUTLS_X509_FMT_PEM;
+
gnutls_global_init();
gnutls_global_set_log_function( tls_log_func);
gnutls_global_set_log_level(info.debug);
case 8:
generate_pkcs12();
break;
+ case 9:
+ pkcs12_info();
+ break;
}
fclose(outfile);
}
exit(1);
}
-
- print_private_key( key);
-
size = sizeof(buffer);
ret = gnutls_x509_crq_export( crq, out_cert_format, buffer, &size);
if (ret < 0) {
exit(1);
}
- fprintf(outfile, "Request: \n%s", buffer);
+ fwrite( buffer, 1, size, outfile);
gnutls_x509_crq_deinit(crq);
gnutls_x509_privkey_deinit(key);
fprintf(stderr, "Generating a PKCS #12 structure...\n");
- if (outfile == stdout) {
- fprintf(stderr, "Sorry, will not output DER data to stdout.\n");
- exit(1);
- }
-
key = load_private_key();
crt = load_cert();
exit(1);
}
- result = gnutls_pkcs12_bag_encrypt( kbag, password, 0);
- if (result < 0) {
- fprintf(stderr, "bag_encrypt: %s\n", gnutls_strerror(result));
- exit(1);
- }
-
/* write the PKCS #12 structure.
*/
result = gnutls_pkcs12_init(&pkcs12);
}
size = sizeof(buffer);
- result = gnutls_pkcs12_export( pkcs12, GNUTLS_X509_FMT_DER, buffer, &size);
+ result = gnutls_pkcs12_export( pkcs12, out_cert_format, buffer, &size);
if (result < 0) {
fprintf(stderr, "pkcs12_export: %s\n", gnutls_strerror(result));
exit(1);
fwrite( buffer, 1, size, outfile);
}
+
+const char* BAGTYPE( gnutls_pkcs12_bag_type x)
+{
+ switch (x) {
+ case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY:
+ return "PKCS #8 Encrypted key";
+ case GNUTLS_BAG_EMPTY:
+ return "Empty";
+ case GNUTLS_BAG_PKCS8_KEY:
+ return "PKCS #8 Key";
+ case GNUTLS_BAG_CERTIFICATE:
+ return "Certificate";
+ case GNUTLS_BAG_ENCRYPTED:
+ return "Encrypted";
+ case GNUTLS_BAG_CRL:
+ return "CRL";
+ default:
+ return "Unknown";
+ }
+}
+
+void print_bag_data(gnutls_pkcs12_bag bag)
+{
+int result;
+int count, i, type;
+gnutls_datum data;
+const char* str;
+gnutls_datum out;
+
+ count = gnutls_pkcs12_bag_get_count( bag);
+ if (count < 0) {
+ fprintf(stderr, "get_count: %s\n", gnutls_strerror(count));
+ exit(1);
+ }
+
+ for (i=0;i<count;i++) {
+ type = gnutls_pkcs12_bag_get_type( bag, i);
+ if (type < 0) {
+ fprintf(stderr, "get_type: %s\n", gnutls_strerror(type));
+ exit(1);
+ }
+
+ fprintf( stderr, "\tType: %s\n", BAGTYPE( type));
+
+ result = gnutls_pkcs12_bag_get_data( bag, i, &data);
+ if (result < 0) {
+ fprintf(stderr, "get_data: %s\n", gnutls_strerror(result));
+ exit(1);
+ }
+
+ switch (type) {
+ case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY:
+ str = "ENCRYPTED PRIVATE KEY";
+ break;
+ case GNUTLS_BAG_PKCS8_KEY:
+ str = "PRIVATE KEY";
+ break;
+ case GNUTLS_BAG_CERTIFICATE:
+ str = "CERTIFICATE";
+ break;
+ case GNUTLS_BAG_CRL:
+ str = "CRL";
+ break;
+ case GNUTLS_BAG_ENCRYPTED:
+ case GNUTLS_BAG_EMPTY:
+ default:
+ str = NULL;
+ }
+
+ if (str != NULL) {
+ gnutls_pem_base64_encode_alloc( str, &data, &out);
+ fprintf( stderr, "%s\n", out.data);
+
+ gnutls_free(out.data);
+ }
+
+ }
+}
+
+void pkcs12_info( void)
+{
+ gnutls_pkcs12 pkcs12;
+ gnutls_pkcs12_bag bag;
+ int result, ret;
+ size_t size;
+ gnutls_datum data;
+ char* password;
+ int index;
+
+ size = fread( buffer, 1, sizeof(buffer)-1, infile);
+ buffer[size] = 0;
+
+ data.data = buffer;
+ data.size = size;
+
+ password = getpass( "Enter password: ");
+
+ result = gnutls_pkcs12_init(&pkcs12);
+ if (result < 0) {
+ fprintf(stderr, "p12_init: %s\n", gnutls_strerror(result));
+ exit(1);
+ }
+
+ result = gnutls_pkcs12_import( pkcs12, &data, in_cert_format, 0);
+ if (result < 0) {
+ fprintf(stderr, "p12_import: %s\n", gnutls_strerror(result));
+ exit(1);
+ }
+
+ result = gnutls_pkcs12_verify_mac( pkcs12, password);
+ if (result < 0) {
+ fprintf(stderr, "verify_mac: %s\n", gnutls_strerror(result));
+ exit(1);
+ }
+
+
+
+ index = 0;
+
+ do {
+ result = gnutls_pkcs12_bag_init( &bag);
+ if (result < 0) {
+ fprintf(stderr, "bag_init: %s\n", gnutls_strerror(result));
+ exit(1);
+ }
+
+ ret = gnutls_pkcs12_get_bag( pkcs12, index, bag);
+ if (ret < 0) {
+ break;
+ }
+
+ result = gnutls_pkcs12_bag_get_count( bag);
+ if (result < 0) {
+ fprintf(stderr, "bag_init: %s\n", gnutls_strerror(result));
+ exit(1);
+ }
+
+ fprintf( stderr, "BAG #%d\n", index);
+ fprintf( stderr, "\tElements: %d\n", result);
+
+ result = gnutls_pkcs12_bag_get_type( bag, 0);
+ if (result < 0) {
+ fprintf(stderr, "bag_init: %s\n", gnutls_strerror(result));
+ exit(1);
+ }
+
+
+ if (result == GNUTLS_BAG_ENCRYPTED) {
+ fprintf( stderr, "\tType: %s\n", BAGTYPE( result));
+ fprintf( stderr, "\n\tDecrypting...\n");
+
+ result = gnutls_pkcs12_bag_decrypt( bag, password);
+
+ if (result < 0) {
+ fprintf(stderr, "bag_decrypt: %s\n", gnutls_strerror(result));
+ exit(1);
+ }
+
+ result = gnutls_pkcs12_bag_get_count( bag);
+ if (result < 0) {
+ fprintf(stderr, "get_count: %s\n", gnutls_strerror(result));
+ exit(1);
+ }
+
+ fprintf( stderr, "\tElements: %d\n", result);
+
+ }
+
+ print_bag_data( bag);
+
+ gnutls_pkcs12_bag_deinit(bag);
+
+ index++;
+ } while( ret == 0);
+
+
+}
+