]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
added capability to print pkcs12 structures.
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Thu, 30 Oct 2003 07:36:18 +0000 (07:36 +0000)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Thu, 30 Oct 2003 07:36:18 +0000 (07:36 +0000)
src/certtool-gaa.c
src/certtool-gaa.h
src/certtool.c
src/certtool.gaa

index 15afa2aade32f79159fc543e66f6fd9b7b0953eb..73e21d8882b611fef006e7872a3eac370fe985d0 100644 (file)
@@ -129,10 +129,12 @@ void gaa_help(void)
        __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.");
@@ -153,17 +155,19 @@ typedef struct _gaainfo gaainfo;
 
 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;
@@ -231,29 +235,31 @@ int gaa_error = 0;
 #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"
 
@@ -536,10 +542,12 @@ int gaa_get_option_num(char *str, int status)
 #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);
@@ -557,10 +565,12 @@ int gaa_get_option_num(char *str, int status)
                        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);
@@ -616,14 +626,14 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
     {
        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;
@@ -633,7 +643,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
                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;
@@ -643,7 +653,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
                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;
@@ -653,7 +663,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
                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;
@@ -663,37 +673,51 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
                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:
@@ -819,10 +843,10 @@ int gaa(int argc, char **argv, gaainfo *gaaval)
     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;
index c5f4c4a6c28d975017a7d584e8fc1196c8837389..cbf73e1f9c926bcce8fa9f59d5082416d0b36c19 100644 (file)
@@ -8,17 +8,19 @@ typedef struct _gaainfo gaainfo;
 
 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;
index 284b8cd931365b2c8f9f666adeabfc1d25699747..0044c6a0f94ac0db05a37031e32e8197f68aeedc 100644 (file)
@@ -8,6 +8,7 @@
 #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);
@@ -25,7 +26,7 @@ static gaainfo info;
 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);
@@ -172,7 +173,7 @@ int size, ret;
 
        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);
@@ -186,7 +187,7 @@ int size, ret;
                }
        }
 
-       fprintf(outfile,"Private key: \n%s\n", buffer);
+       fwrite(buffer, 1, size, outfile);
 }
 
 void generate_private_key( void)
@@ -220,12 +221,12 @@ gnutls_x509_crt generate_certificate( gnutls_x509_privkey *ret_key)
 
 
        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);
@@ -347,7 +348,7 @@ gnutls_x509_crt update_certificate( void)
                fprintf(stderr, "serial: %s\n", gnutls_strerror(result));
                exit(1);
        }
-       
+
        return crt;
 
 }
@@ -372,8 +373,6 @@ void generate_self_signed( void)
                exit(1);
        }
 
-       print_private_key( key);
-
        size = sizeof(buffer);
        result = gnutls_x509_crt_export( crt, out_cert_format, buffer, &size);  
        if (result < 0) {
@@ -381,12 +380,10 @@ void generate_self_signed( void)
                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)
@@ -412,8 +409,6 @@ 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) {
@@ -421,7 +416,7 @@ void generate_signed_certificate( void)
                exit(1);
        }
 
-       fprintf(outfile, "Certificate: \n%s", buffer);
+       fwrite( buffer, 1, size, outfile);
 
        gnutls_x509_crt_deinit(crt);
        gnutls_x509_privkey_deinit(key);
@@ -456,7 +451,7 @@ void update_signed_certificate( void)
                exit(1);
        }
 
-       fprintf(outfile, "Certificate: \n%s", buffer);
+       fwrite( buffer, 1, size, outfile);
 
        gnutls_x509_crt_deinit(crt);
 }
@@ -488,6 +483,9 @@ void gaa_parser(int argc, char **argv)
        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);
@@ -520,6 +518,9 @@ void gaa_parser(int argc, char **argv)
                case 8:
                        generate_pkcs12();
                        break;
+               case 9:
+                       pkcs12_info();
+                       break;
        }
        fclose(outfile);
 }
@@ -1059,9 +1060,6 @@ void generate_request(void)
                exit(1);
        }
 
-
-       print_private_key( key);
-
        size = sizeof(buffer);  
        ret = gnutls_x509_crq_export( crq, out_cert_format, buffer, &size);     
        if (ret < 0) {
@@ -1069,7 +1067,7 @@ void generate_request(void)
                exit(1);
        }
 
-       fprintf(outfile, "Request: \n%s", buffer);
+       fwrite( buffer, 1, size, outfile);
 
        gnutls_x509_crq_deinit(crq);
        gnutls_x509_privkey_deinit(key);
@@ -1266,11 +1264,6 @@ void generate_pkcs12( void)
        
        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();
        
@@ -1370,12 +1363,6 @@ void generate_pkcs12( void)
                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);
@@ -1403,7 +1390,7 @@ void generate_pkcs12( void)
        }
 
        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);
@@ -1412,3 +1399,181 @@ void generate_pkcs12( void)
        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);
+
+       
+}
+
index 1865839edec613a2f751266afa4602e87f1b8eda..99952e5a4e78774682f24c0d065e07b78832f8d5 100644 (file)
@@ -30,6 +30,8 @@ option (load-ca-certificate) STR "FILE" { $ca = $1 } "Certificate authority's ce
 
 option (i, certificate-info) { $action = 2; } "Print information on a certificate."
 
+option (p12-info) { $action = 9; } "Print information on a PKCS #12 structure."
+
 option (k, key-info) { $action = 6; } "Print information on a private key."
 
 option (to-p12) { $action = 8; } "Generate a PKCS #12 structure."
@@ -40,6 +42,9 @@ option (8, pkcs8) { $pkcs8=1 } "Use PKCS #8 format for private keys."
 #int incert_format;
 option (inder) { $incert_format=1 } "Use DER format for input certificates and private keys."
 
+#int outcert_format;
+option (outder) { $outcert_format=1 } "Use DER format for output certificates and private keys."
+
 #int bits;
 option (bits) INT "BITS" { $bits = $1 } "specify the number of bits for key generation."
 
@@ -58,5 +63,5 @@ option (v, version) { certtool_version(); exit(0); } "shows the program version"
 
 init { $bits = 1024; $pkcs8 = 0; $privkey = NULL; $ca=NULL; $ca_privkey = NULL; 
        $debug=1; $request = NULL; $infile = NULL; $outfile = NULL; $cert = NULL; 
-       $incert_format = 0; }
+       $incert_format = 0; $outcert_format = 0; }