summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2004-04-23 06:04:54 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2004-04-23 06:04:54 +0000
commit4993eb96cd5eb93636624a939da6aa12009cf068 (patch)
treeef361aa78806263cb113aa5a26f19277d1fbf6d9 /src
parent267a53d1e72c96b9f73f75db7fb83f4b9a35cafe (diff)
downloadgnutls-4993eb96cd5eb93636624a939da6aa12009cf068.tar.gz
* Changes backported from the development brach:
- Added support for authority key identifier and the extended key usage X.509 extension fields. The certtoool was updated to support them. - Added batch support to certtool. Now it can use templates. - The RC2 cipher is no more included. The one in libgcrypt is now used.
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am12
-rw-r--r--src/certtool-gaa.c144
-rw-r--r--src/certtool-gaa.h6
-rw-r--r--src/certtool.c324
-rw-r--r--src/certtool.gaa6
5 files changed, 287 insertions, 205 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 50d32d78a5..d400495577 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,7 +1,7 @@
EXTRA_DIST = common.h crypt.gaa crypt-gaa.h README.srpcrypt \
README cli.gaa cli-gaa.h serv-gaa.h serv.gaa tls_test.gaa \
tls_test-gaa.h tests.h gnutls-http-serv list.h certtool-gaa.h \
- certtool.gaa getpass.h
+ certtool.gaa getpass.h certtool-cfg.h
SUBDIRS = srp x509 openpgp
@@ -22,8 +22,16 @@ noinst_PROGRAMS = retcodes
retcodes_SOURCES = retcodes.c
retcodes_LDADD = ../lib/libgnutls.la $(LIBGCRYPT_LIBS)
-certtool_SOURCES = certtool-gaa.c certtool.c prime.c getpass.c
+if HAVE_LIBCFG
+certtool_SOURCES = certtool-gaa.c certtool.c prime.c getpass.c certtool-cfg.c
+certtool_LDADD = ../lib/libgnutls.la $(LIBGCRYPT_LIBS) -lcfg+
+else
+certtool_SOURCES = certtool-gaa.c certtool.c prime.c getpass.c certtool-cfg.c \
+ cfg/cfg+.c cfg/cfgfile.c cfg/cmdline.c cfg/parse.c cfg/props.c \
+ cfg/shared.c cfg/platon/str/dynfgets.c cfg/platon/str/strctype.c \
+ cfg/platon/str/strdyn.c cfg/platon/str/strplus.c
certtool_LDADD = ../lib/libgnutls.la $(LIBGCRYPT_LIBS)
+endif
crypt-gaa.c: crypt.gaa
diff --git a/src/certtool-gaa.c b/src/certtool-gaa.c
index fac7e054ef..c2a7e643bb 100644
--- a/src/certtool-gaa.c
+++ b/src/certtool-gaa.c
@@ -1,4 +1,4 @@
-/* File generated by GAA 1.6.5
+/* File generated by GAA 1.6.6
*/
#define GAA_NO_WIN32
#line 1 "certtool.gaa"
@@ -24,7 +24,7 @@ void certtool_version(void);
#endif
#endif
-void* gaa_malloc( size_t size) {
+static void* gaa_malloc( size_t size) {
void* ret;
ret = malloc(size);
if (ret==NULL) {
@@ -34,7 +34,7 @@ void* ret;
return ret;
}
-void __gaa_helpsingle(char short_name, char *name,
+static void __gaa_helpsingle(char short_name, char *name,
char *arg_desc, char *opt_help)
{
int col1, col3, col4, tabsize = 3, curr;
@@ -159,6 +159,7 @@ void gaa_help(void)
__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.");
+ __gaa_helpsingle(0, "template", "FILE ", "Template file to use for non interactive operation.");
__gaa_helpsingle('d', "debug", "LEVEL ", "specify the debug level. Default is 1.");
__gaa_helpsingle('h', "help", "", "shows this help text");
__gaa_helpsingle('v', "version", "", "shows the program's version");
@@ -177,8 +178,10 @@ typedef struct _gaainfo gaainfo;
struct _gaainfo
{
-#line 90 "certtool.gaa"
+#line 94 "certtool.gaa"
int debug;
+#line 90 "certtool.gaa"
+ char *template;
#line 87 "certtool.gaa"
char *infile;
#line 84 "certtool.gaa"
@@ -222,7 +225,7 @@ extern "C"
void gaa_help(void);
- int gaa_file(char *name, gaainfo *gaaval);
+ int gaa_file(const char *name, gaainfo *gaaval);
#ifdef __cplusplus
}
@@ -241,8 +244,8 @@ gaa_error = 1; \
return x; \
}
-char *gaa_current_option;
-int gaa_error = 0;
+static char *gaa_current_option;
+static int gaa_error = 0;
/* Generated by gaa */
@@ -263,40 +266,41 @@ int gaa_error = 0;
#define GAA_MULTIPLE_OPTION 3
#define GAA_REST 0
-#define GAA_NB_OPTION 33
+#define GAA_NB_OPTION 34
#define GAAOPTID_copyright 1
#define GAAOPTID_version 2
#define GAAOPTID_help 3
#define GAAOPTID_debug 4
-#define GAAOPTID_infile 5
-#define GAAOPTID_outfile 6
-#define GAAOPTID_bits 7
-#define GAAOPTID_outder 8
-#define GAAOPTID_inder 9
-#define GAAOPTID_export_ciphers 10
-#define GAAOPTID_dsa 11
-#define GAAOPTID_pkcs8 12
-#define GAAOPTID_to_p12 13
-#define GAAOPTID_key_info 14
-#define GAAOPTID_p7_info 15
-#define GAAOPTID_p12_info 16
-#define GAAOPTID_crl_info 17
-#define GAAOPTID_certificate_info 18
-#define GAAOPTID_password 19
-#define GAAOPTID_load_ca_certificate 20
-#define GAAOPTID_load_ca_privkey 21
-#define GAAOPTID_load_certificate 22
-#define GAAOPTID_load_request 23
-#define GAAOPTID_load_privkey 24
-#define GAAOPTID_generate_dh_params 25
-#define GAAOPTID_verify_crl 26
-#define GAAOPTID_verify_chain 27
-#define GAAOPTID_generate_request 28
-#define GAAOPTID_generate_privkey 29
-#define GAAOPTID_update_certificate 30
-#define GAAOPTID_generate_crl 31
-#define GAAOPTID_generate_certificate 32
-#define GAAOPTID_generate_self_signed 33
+#define GAAOPTID_template 5
+#define GAAOPTID_infile 6
+#define GAAOPTID_outfile 7
+#define GAAOPTID_bits 8
+#define GAAOPTID_outder 9
+#define GAAOPTID_inder 10
+#define GAAOPTID_export_ciphers 11
+#define GAAOPTID_dsa 12
+#define GAAOPTID_pkcs8 13
+#define GAAOPTID_to_p12 14
+#define GAAOPTID_key_info 15
+#define GAAOPTID_p7_info 16
+#define GAAOPTID_p12_info 17
+#define GAAOPTID_crl_info 18
+#define GAAOPTID_certificate_info 19
+#define GAAOPTID_password 20
+#define GAAOPTID_load_ca_certificate 21
+#define GAAOPTID_load_ca_privkey 22
+#define GAAOPTID_load_certificate 23
+#define GAAOPTID_load_request 24
+#define GAAOPTID_load_privkey 25
+#define GAAOPTID_generate_dh_params 26
+#define GAAOPTID_verify_crl 27
+#define GAAOPTID_verify_chain 28
+#define GAAOPTID_generate_request 29
+#define GAAOPTID_generate_privkey 30
+#define GAAOPTID_update_certificate 31
+#define GAAOPTID_generate_crl 32
+#define GAAOPTID_generate_certificate 33
+#define GAAOPTID_generate_self_signed 34
#line 168 "gaa.skel"
@@ -438,13 +442,13 @@ if(k > 1) \
}
-char **GAAargv;
-int GAAargc;
-char *gaa_arg_used;
-int gaa_processing_file = 0;
-int inited = 0;
+static char **GAAargv;
+static int GAAargc;
+static char *gaa_arg_used;
+static int gaa_processing_file = 0;
+static int inited = 0;
-int gaa_getint(char *arg)
+static int gaa_getint(char *arg)
{
int tmp;
char a;
@@ -456,7 +460,7 @@ int gaa_getint(char *arg)
return tmp;
}
-char gaa_getchar(char *arg)
+static char gaa_getchar(char *arg)
{
if(strlen(arg) != 1)
{
@@ -466,11 +470,11 @@ char gaa_getchar(char *arg)
return arg[0];
}
-char* gaa_getstr(char *arg)
+static char* gaa_getstr(char *arg)
{
return arg;
}
-float gaa_getfloat(char *arg)
+static float gaa_getfloat(char *arg)
{
float tmp;
char a;
@@ -489,6 +493,12 @@ struct GAAOPTION_debug
int size1;
};
+struct GAAOPTION_template
+{
+ char* arg1;
+ int size1;
+};
+
struct GAAOPTION_infile
{
char* arg1;
@@ -544,7 +554,7 @@ struct GAAOPTION_load_privkey
};
#line 349 "gaa.skel"
-int gaa_is_an_argument(char *str)
+static int gaa_is_an_argument(char *str)
{
#ifdef GAA_WIN32
if(str[0] == '/' && str[1] != 0)
@@ -567,12 +577,13 @@ int gaa_is_an_argument(char *str)
return GAA_MULTIPLE_OPTION;
}
-int gaa_get_option_num(char *str, int status)
+static int gaa_get_option_num(char *str, int status)
{
switch(status)
{
case GAA_LETTER_OPTION:
GAA_CHECK1STR("d", GAAOPTID_debug);
+ GAA_CHECK1STR("", GAAOPTID_template);
GAA_CHECK1STR("", GAAOPTID_infile);
GAA_CHECK1STR("", GAAOPTID_outfile);
GAA_CHECK1STR("", GAAOPTID_bits);
@@ -615,6 +626,7 @@ int gaa_get_option_num(char *str, int status)
GAA_CHECKSTR("version", GAAOPTID_version);
GAA_CHECKSTR("help", GAAOPTID_help);
GAA_CHECKSTR("debug", GAAOPTID_debug);
+ GAA_CHECKSTR("template", GAAOPTID_template);
GAA_CHECKSTR("infile", GAAOPTID_infile);
GAA_CHECKSTR("outfile", GAAOPTID_outfile);
GAA_CHECKSTR("bits", GAAOPTID_bits);
@@ -652,11 +664,12 @@ int gaa_get_option_num(char *str, int status)
return GAA_ERROR_NOMATCH;
}
-int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
+static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
{
int OK = 0;
int gaa_last_non_option;
struct GAAOPTION_debug GAATMP_debug;
+ struct GAAOPTION_template GAATMP_template;
struct GAAOPTION_infile GAATMP_infile;
struct GAAOPTION_outfile GAATMP_outfile;
struct GAAOPTION_bits GAATMP_bits;
@@ -688,21 +701,21 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
{
case GAAOPTID_copyright:
OK = 0;
-#line 96 "certtool.gaa"
+#line 100 "certtool.gaa"
{ print_license(); exit(0); ;};
return GAA_OK;
break;
case GAAOPTID_version:
OK = 0;
-#line 95 "certtool.gaa"
+#line 99 "certtool.gaa"
{ certtool_version(); exit(0); ;};
return GAA_OK;
break;
case GAAOPTID_help:
OK = 0;
-#line 93 "certtool.gaa"
+#line 97 "certtool.gaa"
{ gaa_help(); exit(0); ;};
return GAA_OK;
@@ -712,11 +725,21 @@ 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 91 "certtool.gaa"
+#line 95 "certtool.gaa"
{ gaaval->debug = GAATMP_debug.arg1 ;};
return GAA_OK;
break;
+ case GAAOPTID_template:
+ OK = 0;
+ GAA_TESTMOREARGS;
+ GAA_FILL(GAATMP_template.arg1, gaa_getstr, GAATMP_template.size1);
+ gaa_index++;
+#line 91 "certtool.gaa"
+{ gaaval->template = GAATMP_template.arg1 ;};
+
+ return GAA_OK;
+ break;
case GAAOPTID_infile:
OK = 0;
GAA_TESTMOREARGS;
@@ -971,11 +994,11 @@ int gaa(int argc, char **argv, gaainfo *gaaval)
if(inited == 0)
{
-#line 98 "certtool.gaa"
+#line 102 "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->outcert_format = 0; gaaval->action=-1; gaaval->pass = NULL;
- gaaval->export = 0; ;};
+ gaaval->export = 0; gaaval->template = NULL; ;};
}
inited = 1;
@@ -1091,11 +1114,10 @@ struct gaastrnode
typedef struct gaastrnode gaa_str_node;
-int gaa_internal_get_next_str(FILE *file, gaa_str_node *tmp_str, int argc)
+static int gaa_internal_get_next_str(FILE *file, gaa_str_node *tmp_str, int argc)
{
int pos_ini;
int a;
- char ca;
int i = 0, len = 0, newline = 0;
if(argc == 1) {
@@ -1144,12 +1166,12 @@ int gaa_internal_get_next_str(FILE *file, gaa_str_node *tmp_str, int argc)
fseek(file,pos_ini, SEEK_SET);
do
{
- if(fscanf(file, "%c", &ca) != 1)
- {
+ a = fgetc( file);
+
+ if (a == EOF) {
i+=2;
break;
}
- a = ca;
tmp_str->str[i] = a;
i++;
}
@@ -1163,7 +1185,7 @@ int gaa_internal_get_next_str(FILE *file, gaa_str_node *tmp_str, int argc)
return -1;
}
-int gaa_file(char *name, gaainfo *gaaval)
+int gaa_file(const char *name, gaainfo *gaaval)
{
gaa_str_node *first_str, **tmp_str, *tmp_str2;
int rval, i;
diff --git a/src/certtool-gaa.h b/src/certtool-gaa.h
index 2bef4af05b..caadbb473b 100644
--- a/src/certtool-gaa.h
+++ b/src/certtool-gaa.h
@@ -8,8 +8,10 @@ typedef struct _gaainfo gaainfo;
struct _gaainfo
{
-#line 90 "certtool.gaa"
+#line 94 "certtool.gaa"
int debug;
+#line 90 "certtool.gaa"
+ char *template;
#line 87 "certtool.gaa"
char *infile;
#line 84 "certtool.gaa"
@@ -53,7 +55,7 @@ extern "C"
void gaa_help(void);
- int gaa_file(char *name, gaainfo *gaaval);
+ int gaa_file(const char *name, gaainfo *gaaval);
#ifdef __cplusplus
}
diff --git a/src/certtool.c b/src/certtool.c
index e2cbaf1e09..ea9547e95b 100644
--- a/src/certtool.c
+++ b/src/certtool.c
@@ -33,8 +33,7 @@
#include <gnutls/pkcs12.h>
#include <unistd.h>
#include <getpass.h>
-
-#define UNKNOWN "Unknown"
+#include <certtool-cfg.h>
static void print_crl_info( gnutls_x509_crl crl, FILE* out, int all);
int generate_prime(int bits);
@@ -60,8 +59,14 @@ gnutls_x509_crt* load_cert_list(int mand, int *size);
static gaainfo info;
FILE* outfile;
FILE* infile;
-int in_cert_format;
-int out_cert_format;
+static int in_cert_format;
+static int out_cert_format;
+
+#define UNKNOWN "Unknown"
+
+/* non interactive operation if set
+ */
+int batch;
unsigned char buffer[50*1024];
const int buffer_size = sizeof(buffer);
@@ -73,6 +78,7 @@ static void tls_log_func( int level, const char* str)
int main(int argc, char** argv)
{
+ cfg_init();
gaa_parser(argc, argv);
return 0;
@@ -80,81 +86,6 @@ int main(int argc, char** argv)
-static void read_crt_set( gnutls_x509_crt crt, const char* input_str, const char* oid)
-{
-char input[128];
-int ret;
-
- fputs( input_str, stderr);
- fgets( input, sizeof(input), stdin);
-
- if (strlen(input)==1) /* only newline */ return;
-
- ret = gnutls_x509_crt_set_dn_by_oid(crt, oid, 0, input, strlen(input)-1);
- if (ret < 0) {
- fprintf(stderr, "set_dn: %s\n", gnutls_strerror(ret));
- exit(1);
- }
-}
-
-static void read_crq_set( gnutls_x509_crq crq, const char* input_str, const char* oid)
-{
-char input[128];
-int ret;
-
- fputs( input_str, stderr);
- fgets( input, sizeof(input), stdin);
-
- if (strlen(input)==1) /* only newline */ return;
-
- ret = gnutls_x509_crq_set_dn_by_oid(crq, oid, 0, input, strlen(input)-1);
- if (ret < 0) {
- fprintf(stderr, "set_dn: %s\n", gnutls_strerror(ret));
- exit(1);
- }
-}
-
-static int read_int( const char* input_str)
-{
-char input[128];
-
- fputs( input_str, stderr);
- fgets( input, sizeof(input), stdin);
-
- if (strlen(input)==1) /* only newline */ return 0;
-
- return atoi(input);
-}
-
-static const char* read_str( const char* input_str)
-{
-static char input[128];
-int len;
-
- fputs( input_str, stderr);
- if (fgets( input, sizeof(input), stdin) == NULL) return NULL;
-
- len = strlen(input);
- if ( (len > 0) && (input[len-1] == '\n') ) input[len-1] = 0;
- if (input[0] == 0) return NULL;
-
- return input;
-}
-
-static int read_yesno( const char* input_str)
-{
-char input[128];
-
- fputs( input_str, stderr);
- fgets( input, sizeof(input), stdin);
-
- if (strlen(input)==1) /* only newline */ return 0;
-
- if (input[0] == 'y' || input[0] == 'Y') return 1;
-
- return 0;
-}
-
static gnutls_x509_privkey generate_private_key_int( void)
{
gnutls_x509_privkey key;
@@ -217,6 +148,27 @@ static void print_key_usage( unsigned int x, FILE* out)
fprintf(out,"\t\tKey decipher only.\n");
}
+static void print_key_purpose( const char* x, FILE* out)
+{
+ if (strcasecmp( x, GNUTLS_KP_TLS_WWW_SERVER)==0)
+ fprintf(out,"\t\tTLS WWW Server.\n");
+ else if (strcasecmp( x, GNUTLS_KP_TLS_WWW_CLIENT)==0)
+ fprintf(out,"\t\tTLS WWW Client.\n");
+ else if (strcasecmp( x, GNUTLS_KP_CODE_SIGNING)==0)
+ fprintf(out,"\t\tCode signing.\n");
+ else if (strcasecmp( x, GNUTLS_KP_EMAIL_PROTECTION)==0)
+ fprintf(out,"\t\tEmail protection.\n");
+ else if (strcasecmp( x, GNUTLS_KP_TIME_STAMPING)==0)
+ fprintf(out,"\t\tTime stamping.\n");
+ else if (strcasecmp( x, GNUTLS_KP_OCSP_SIGNING)==0)
+ fprintf(out,"\t\tOCSP signing.\n");
+ else if (strcasecmp( x, GNUTLS_KP_ANY)==0)
+ fprintf(out,"\t\tAny purpose.\n");
+ else fprintf(out,"\t\t%s\n", x);
+}
+
+
+
static void print_private_key( gnutls_x509_privkey key)
{
int ret;
@@ -237,7 +189,7 @@ size_t size;
if (info.export) flags = GNUTLS_PKCS_USE_PKCS12_RC2_40;
else flags = GNUTLS_PKCS_USE_PKCS12_3DES;
- if ((pass=read_pass("Enter password: ")) == NULL) flags = GNUTLS_PKCS_PLAIN;
+ if ((pass=get_pass()) == NULL) flags = GNUTLS_PKCS_PLAIN;
size = sizeof(buffer);
ret = gnutls_x509_privkey_export_pkcs8( key, out_cert_format, pass, flags, buffer, &size);
@@ -264,11 +216,12 @@ gnutls_x509_privkey key;
}
-gnutls_x509_crt generate_certificate( gnutls_x509_privkey *ret_key)
+gnutls_x509_crt generate_certificate( gnutls_x509_privkey *ret_key,
+ gnutls_x509_crt ca_crt)
{
gnutls_x509_crt crt;
gnutls_x509_privkey key = NULL;
- int size, serial;
+ int size, serial, client;
int days, result, ca_status;
const char* str;
int vers = 3; /* the default version in the certificate
@@ -289,18 +242,20 @@ gnutls_x509_crt generate_certificate( gnutls_x509_privkey *ret_key)
key = load_private_key(1);
+ if (!batch)
fprintf(stderr, "Please enter the details of the certificate's distinguished name. "
"Just press enter to ignore a field.\n");
- read_crt_set( crt, "Country name (2 chars): ", GNUTLS_OID_X520_COUNTRY_NAME);
- read_crt_set( crt, "Organization name: ", GNUTLS_OID_X520_ORGANIZATION_NAME);
- read_crt_set( crt, "Organizational unit name: ", GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME);
- read_crt_set( crt, "Locality name: ", GNUTLS_OID_X520_LOCALITY_NAME);
- read_crt_set( crt, "State or province name: ", GNUTLS_OID_X520_LOCALITY_NAME);
- read_crt_set( crt, "Common name: ", GNUTLS_OID_X520_COMMON_NAME);
+ get_country_crt_set( crt);
+ get_organization_crt_set(crt);
+ get_unit_crt_set( crt);
+ get_locality_crt_set( crt);
+ get_state_crt_set( crt);
+ get_cn_crt_set( crt);
- fprintf(stderr, "This field should not be used in new certificates.\n");
- read_crt_set( crt, "E-mail: ", GNUTLS_OID_PKCS9_EMAIL);
+ if (!batch) fprintf(stderr, "This field should not be used in new certificates.\n");
+
+ get_pkcs9_email_crt_set( crt);
result = gnutls_x509_crt_set_key( crt, key);
if (result < 0) {
@@ -317,7 +272,7 @@ gnutls_x509_crt generate_certificate( gnutls_x509_privkey *ret_key)
}
- serial = read_int( "Enter the certificate's serial number (decimal): ");
+ serial = get_serial();
buffer[3] = serial & 0xff;
buffer[2] = (serial >> 8) & 0xff;
buffer[1] = (serial >> 16) & 0xff;
@@ -330,12 +285,11 @@ gnutls_x509_crt generate_certificate( gnutls_x509_privkey *ret_key)
}
- fprintf(stderr, "\n\nActivation/Expiration time.\n");
+ if (!batch) fprintf(stderr, "\n\nActivation/Expiration time.\n");
+
gnutls_x509_crt_set_activation_time( crt, time(NULL));
- do {
- days = read_int( "The generated certificate will expire in (days): ");
- } while( days==0);
+ days = get_days();
result = gnutls_x509_crt_set_expiration_time( crt, time(NULL)+days*24*60*60);
if (result < 0) {
@@ -344,9 +298,9 @@ gnutls_x509_crt generate_certificate( gnutls_x509_privkey *ret_key)
}
- fprintf(stderr, "\n\nExtensions.\n");
+ if (!batch) fprintf(stderr, "\n\nExtensions.\n");
- ca_status = read_yesno( "Does the certificate belong to an authority? (Y/N): ");
+ ca_status = get_ca_status();
result = gnutls_x509_crt_set_ca_status( crt, ca_status);
if (result < 0) {
@@ -354,9 +308,18 @@ gnutls_x509_crt generate_certificate( gnutls_x509_privkey *ret_key)
exit(1);
}
- server = read_yesno( "Is this a web server certificate? (Y/N): ");
+ client = get_tls_client_status();
+ if (client != 0) {
+ result = gnutls_x509_crt_set_key_purpose_oid( crt, GNUTLS_KP_TLS_WWW_CLIENT, 0);
+ if (result < 0) {
+ fprintf(stderr, "key_kp: %s\n", gnutls_strerror(result));
+ exit(1);
+ }
+ }
+
+ server = get_tls_server_status();
if (server != 0) {
- str = read_str( "Enter the dnsName of the subject of the certificate: ");
+ str = get_dns_name();
if (str != NULL) {
result = gnutls_x509_crt_set_subject_alternative_name( crt, GNUTLS_SAN_DNSNAME, str);
if (result < 0) {
@@ -364,9 +327,16 @@ gnutls_x509_crt generate_certificate( gnutls_x509_privkey *ret_key)
exit(1);
}
}
+
+ result = gnutls_x509_crt_set_key_purpose_oid( crt, GNUTLS_KP_TLS_WWW_SERVER, 0);
+ if (result < 0) {
+ fprintf(stderr, "key_kp: %s\n", gnutls_strerror(result));
+ exit(1);
+ }
+
} else {
- str = read_str( "Enter the e-mail of the subject of the certificate: ");
+ str = get_email();
if (str != NULL) {
result = gnutls_x509_crt_set_subject_alternative_name( crt, GNUTLS_SAN_RFC822NAME, str);
@@ -380,33 +350,54 @@ gnutls_x509_crt generate_certificate( gnutls_x509_privkey *ret_key)
if (!ca_status || server) {
int pk;
- const char* msg1, *msg2;
-
- if (server) msg1 = "Will the certificate be used for signing (DHE and RSA-EXPORT ciphersuites)? (Y/N): ";
- else msg1 = "Will the certificate be used for signing (required for TLS)? (Y/N): ";
- if (server) msg2 = "Will the certificate be used for encryption (RSA ciphersuites)? (Y/N): ";
- else msg2 = "Will the certificate be used for encryption (not required for TLS)? (Y/N): ";
pk = gnutls_x509_crt_get_pk_algorithm( crt, NULL);
if (pk != GNUTLS_PK_DSA) { /* DSA keys can only sign.
*/
- result = read_yesno( msg1);
+ result = get_sign_status(server);
if (result) usage |= GNUTLS_KEY_DIGITAL_SIGNATURE;
- result = read_yesno( msg2);
+ result = get_encrypt_status( server);
if (result) usage |= GNUTLS_KEY_KEY_ENCIPHERMENT;
} else usage |= GNUTLS_KEY_DIGITAL_SIGNATURE;
}
if (ca_status) {
- result = read_yesno( "Will the certificate be used to sign other certificates? (Y/N): ");
+ result = get_cert_sign_status();
if (result) usage |= GNUTLS_KEY_KEY_CERT_SIGN;
- result = read_yesno( "Will the certificate be used to sign CRLs? (Y/N): ");
+ result = get_crl_sign_status();
if (result) usage |= GNUTLS_KEY_CRL_SIGN;
+
+ result = get_code_sign_status();
+ if (result) {
+ result = gnutls_x509_crt_set_key_purpose_oid( crt, GNUTLS_KP_CODE_SIGNING, 0);
+ if (result < 0) {
+ fprintf(stderr, "key_kp: %s\n", gnutls_strerror(result));
+ exit(1);
+ }
+ }
+
+ result = get_ocsp_sign_status();
+ if (result) {
+ result = gnutls_x509_crt_set_key_purpose_oid( crt, GNUTLS_KP_OCSP_SIGNING, 0);
+ if (result < 0) {
+ fprintf(stderr, "key_kp: %s\n", gnutls_strerror(result));
+ exit(1);
+ }
+ }
+
+ result = get_time_stamp_status();
+ if (result) {
+ result = gnutls_x509_crt_set_key_purpose_oid( crt, GNUTLS_KP_TIME_STAMPING, 0);
+ if (result < 0) {
+ fprintf(stderr, "key_kp: %s\n", gnutls_strerror(result));
+ exit(1);
+ }
+ }
}
if (usage != 0) {
@@ -437,6 +428,20 @@ gnutls_x509_crt generate_certificate( gnutls_x509_privkey *ret_key)
}
}
+ /* Authority Key ID.
+ */
+ if (ca_crt != NULL) {
+ size = sizeof(buffer);
+ result = gnutls_x509_crt_get_key_id(ca_crt, 0, buffer, &size);
+ if (result >= 0) {
+ result = gnutls_x509_crt_set_authority_key_id( crt, buffer, size);
+ if (result < 0) {
+ fprintf(stderr, "set_authority_key_id: %s\n", gnutls_strerror(result));
+ exit(1);
+ }
+ }
+ }
+
*ret_key = key;
return crt;
@@ -471,9 +476,7 @@ gnutls_x509_crl generate_crl( void)
fprintf(stderr, "\n\nthisUpdate/nextUpdate time.\n");
gnutls_x509_crl_set_this_update( crl, time(NULL));
- do {
- days = read_int( "The next CRL will be issued in (days): ");
- } while( days==0);
+ days = get_crl_next_update();
result = gnutls_x509_crl_set_next_update( crl, time(NULL)+days*24*60*60);
if (result < 0) {
@@ -509,9 +512,7 @@ gnutls_x509_crt update_certificate( void)
fprintf(stderr, "Activation/Expiration time.\n");
gnutls_x509_crt_set_activation_time( crt, time(NULL));
- do {
- days = read_int( "The updated certificate will expire in (days): ");
- } while( days==0);
+ days = get_days();
result = gnutls_x509_crt_set_expiration_time( crt, time(NULL)+days*24*60*60);
if (result < 0) {
@@ -534,9 +535,9 @@ void generate_self_signed( void)
fprintf(stderr, "Generating a self signed certificate...\n");
- crt = generate_certificate( &key);
+ crt = generate_certificate( &key, NULL);
- uri = read_str( "Enter the URI of the CRL distribution point: ");
+ uri = get_crl_dist_point_url();
if (uri) {
result = gnutls_x509_crt_set_crl_dist_points( crt, GNUTLS_SAN_URI,
uri, 0 /* all reasons */);
@@ -583,7 +584,7 @@ void generate_signed_certificate( void)
ca_key = load_ca_private_key();
ca_crt = load_ca_cert();
- crt = generate_certificate( &key);
+ crt = generate_certificate( &key, ca_crt);
/* Copy the CRL distribution points.
*/
@@ -718,6 +719,12 @@ int ret;
if (info.outcert_format) out_cert_format = GNUTLS_X509_FMT_DER;
else out_cert_format = GNUTLS_X509_FMT_PEM;
+ batch = 0;
+ if (info.template) {
+ batch = 1;
+ template_parse( info.template);
+ }
+
gnutls_global_set_log_function( tls_log_func);
gnutls_global_set_log_level(info.debug);
@@ -788,7 +795,9 @@ static inline int known_oid( const char* oid)
if (strcmp(oid, "2.5.29.17") == 0 ||
strcmp( oid, "2.5.29.19") == 0 ||
strcmp( oid, "2.5.29.31") == 0 ||
+ strcmp( oid, "2.5.29.37") == 0 ||
strcmp( oid, "2.5.29.14") == 0 ||
+ strcmp( oid, "2.5.29.35") == 0 ||
strcmp( oid, "2.5.29.15") == 0)
return 1;
@@ -831,7 +840,7 @@ void certificate_info( void)
static void print_certificate_info( gnutls_x509_crt crt, FILE* out, unsigned int all)
{
int ret;
- unsigned int i, indx, j;
+ unsigned int i, indx, j, version;
unsigned int critical, key_usage;
time_t tim;
char serial[40];
@@ -845,7 +854,8 @@ static void print_certificate_info( gnutls_x509_crt crt, FILE* out, unsigned int
fprintf( out, "\n\nX.509 certificate info:\n\n");
- fprintf(out, "Version: %d\n", gnutls_x509_crt_get_version(crt));
+ version = gnutls_x509_crt_get_version(crt);
+ fprintf(out, "Version: %d\n", version);
/* serial number
*/
@@ -910,8 +920,8 @@ static void print_certificate_info( gnutls_x509_crt crt, FILE* out, unsigned int
fprintf(out, "%s\n", cprint);
-
- fprintf(out, "\nX.509 Extensions:\n");
+ if (version >= 3)
+ fprintf(out, "\nX.509 Extensions:\n");
/* subject alternative name
*/
@@ -997,6 +1007,24 @@ static void print_certificate_info( gnutls_x509_crt crt, FILE* out, unsigned int
print_key_usage(key_usage, out);
}
+ /* Key Purpose identifiers.
+ */
+ i = 0;
+
+ size = sizeof(buffer);
+ if ((ret=gnutls_x509_crt_get_key_purpose_oid( crt, 0, buffer, &size, &critical)) >= 0) {
+ fprintf(out, "\tKey purpose OIDs: %s\n", critical?"(critical)":"");
+ do {
+ size = sizeof(buffer);
+ ret = gnutls_x509_crt_get_key_purpose_oid( crt, i, buffer, &size, &critical);
+
+ if (ret >= 0) {
+ print_key_purpose(buffer, out);
+ }
+ i++;
+ } while(ret >= 0);
+ }
+
/* Subject Key ID
*/
size = sizeof(buffer);
@@ -1016,6 +1044,25 @@ static void print_certificate_info( gnutls_x509_crt crt, FILE* out, unsigned int
fprintf(out, "\tSubject Key ID: %s\n\t\t%s\n", critical?"(critical)":"", printable);
}
+ /* Authority Key ID
+ */
+ size = sizeof(buffer);
+ ret = gnutls_x509_crt_get_authority_key_id(crt, buffer, &size, &critical);
+
+ if (ret < 0 && ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
+ {
+ fprintf(out, "Error getting authority key id: %s\n", gnutls_strerror(ret));
+ }
+
+ if (ret >= 0) {
+ print = printable;
+ for (i = 0; i < size; i++) {
+ sprintf(print, "%.2x ", (unsigned char) buffer[i]);
+ print += 3;
+ }
+ fprintf(out, "\tAuthority Key ID: %s\n\t\t%s\n", critical?"(critical)":"", printable);
+ }
+
/* other extensions:
*/
indx = 0;
@@ -1038,6 +1085,7 @@ static void print_certificate_info( gnutls_x509_crt crt, FILE* out, unsigned int
size = sizeof(buffer);
ret = gnutls_x509_crt_get_extension_by_oid( crt, oid, indx, buffer, &size, &critical);
+
if (ret >= 0) {
if (critical)
fprintf(out, "(critical)\n");
@@ -1093,7 +1141,7 @@ static void print_certificate_info( gnutls_x509_crt crt, FILE* out, unsigned int
fprintf(out, "\n");
- if (out==stderr) /* interactive */
+ if (out==stderr && batch == 0) /* interactive */
if (read_yesno( "Is the above information ok? (Y/N): ")==0) {
exit(1);
}
@@ -1228,7 +1276,7 @@ void privkey_info( void)
if (!info.pkcs8) {
ret = gnutls_x509_privkey_import(key, &pem, in_cert_format);
} else {
- pass = read_pass("Enter password: ");
+ pass = get_pass();
ret = gnutls_x509_privkey_import_pkcs8(key, &pem, in_cert_format, pass, 0);
}
@@ -1311,7 +1359,7 @@ const char* pass;
if (!info.pkcs8)
ret = gnutls_x509_privkey_import( key, &dat, in_cert_format);
else {
- pass = read_pass("Enter password: ");
+ pass = get_pass();
ret = gnutls_x509_privkey_import_pkcs8( key, &dat, in_cert_format,
pass, 0);
}
@@ -1403,7 +1451,7 @@ size_t size;
if (!info.pkcs8)
ret = gnutls_x509_privkey_import( key, &dat, in_cert_format);
else {
- pass = read_pass("Enter password: ");
+ pass = get_pass();
ret = gnutls_x509_privkey_import_pkcs8( key, &dat, in_cert_format,
pass, 0);
}
@@ -1569,12 +1617,12 @@ void generate_request(void)
*/
key = generate_private_key_int();
- read_crq_set( crq, "Country name (2 chars): ", GNUTLS_OID_X520_COUNTRY_NAME);
- read_crq_set( crq, "Organization name: ", GNUTLS_OID_X520_ORGANIZATION_NAME);
- read_crq_set( crq, "Organizational unit name: ", GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME);
- read_crq_set( crq, "Locality name: ", GNUTLS_OID_X520_LOCALITY_NAME);
- read_crq_set( crq, "State or province name: ", GNUTLS_OID_X520_LOCALITY_NAME);
- read_crq_set( crq, "Common name: ", GNUTLS_OID_X520_COMMON_NAME);
+ get_country_crq_set( crq);
+ get_organization_crq_set(crq);
+ get_unit_crq_set( crq);
+ get_locality_crq_set( crq);
+ get_state_crq_set( crq);
+ get_cn_crq_set( crq);
ret = gnutls_x509_crq_set_version( crq, 1);
if (ret < 0) {
@@ -1582,7 +1630,7 @@ void generate_request(void)
exit(1);
}
- pass = read_pass("Enter a challenge password: ");
+ pass = get_challenge_pass();
if (pass != NULL) {
ret = gnutls_x509_crq_set_challenge_password( crq, pass);
@@ -2001,11 +2049,9 @@ void generate_pkcs12( void)
key = load_private_key(1);
crt = load_cert(0);
- do {
- name = read_str("Enter a name for the key: ");
- } while( name == NULL);
+ name = get_pkcs12_key_name();
- password = read_pass( "Enter password: ");
+ password = get_pass();
result = gnutls_pkcs12_bag_init( &bag);
if (result < 0) {
@@ -2238,7 +2284,7 @@ void pkcs12_info( void)
data.data = buffer;
data.size = size;
- password = read_pass( "Enter password: ");
+ password = get_pass();
result = gnutls_pkcs12_init(&pkcs12);
if (result < 0) {
diff --git a/src/certtool.gaa b/src/certtool.gaa
index 9fb257e93f..3793fca9fc 100644
--- a/src/certtool.gaa
+++ b/src/certtool.gaa
@@ -87,6 +87,10 @@ option (outfile) STR "FILE" { $outfile = $1 } "Output file."
#char *infile;
option (infile) STR "FILE" { $infile = $1 } "Output file."
+#char *template;
+option (template) STR "FILE" { $template = $1 } "Template file to use for non interactive operation."
+
+
#int debug;
option (d, debug) INT "LEVEL" { $debug = $1 } "specify the debug level. Default is 1."
@@ -98,5 +102,5 @@ option ( copyright) { print_license(); exit(0); } "shows the program's license"
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; $outcert_format = 0; $action=-1; $pass = NULL;
- $export = 0; }
+ $export = 0; $template = NULL; }