From: Nikos Mavrogiannopoulos Date: Sat, 4 Oct 2008 06:27:41 +0000 (+0300) Subject: Added initial support for certificate requests handling of X.509 extensions. X-Git-Tag: gnutls_2_7_0~54 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2fbad03b30689fcc2995784ac3f570279680d7ba;p=thirdparty%2Fgnutls.git Added initial support for certificate requests handling of X.509 extensions. Added support to certtool to handle these extensions (add/read) --- diff --git a/includes/gnutls/x509.h b/includes/gnutls/x509.h index 1d512fda9a..ee6e937cb4 100644 --- a/includes/gnutls/x509.h +++ b/includes/gnutls/x509.h @@ -651,6 +651,11 @@ extern "C" struct gnutls_x509_crq_int; typedef struct gnutls_x509_crq_int *gnutls_x509_crq_t; + int gnutls_x509_crq_print (gnutls_x509_crq_t crq, + gnutls_certificate_print_formats_t format, + gnutls_datum_t * out); + + int gnutls_x509_crq_init (gnutls_x509_crq_t * crq); void gnutls_x509_crq_deinit (gnutls_x509_crq_t crq); int gnutls_x509_crq_import (gnutls_x509_crq_t crq, @@ -703,7 +708,50 @@ extern "C" int gnutls_x509_crq_set_key_rsa_raw (gnutls_x509_crq_t crq, const gnutls_datum_t * m, const gnutls_datum_t * e); + int gnutls_x509_crq_set_subject_alt_name (gnutls_x509_crq_t crq, + gnutls_x509_subject_alt_name_t type, + const void *data, + unsigned int data_size, + unsigned int flags); + int gnutls_x509_crq_set_key_usage (gnutls_x509_crq_t crq, unsigned int usage); + int gnutls_x509_crq_set_basic_constraints (gnutls_x509_crq_t crq, + unsigned int ca, int pathLenConstraint); + + int gnutls_x509_crq_get_extension_data (gnutls_x509_crq_t cert, int indx, + void *data, size_t * sizeof_data); + int gnutls_x509_crq_get_extension_info (gnutls_x509_crq_t cert, int indx, + void *oid, size_t * sizeof_oid, + int *critical); + int gnutls_x509_crq_get_attribute_data (gnutls_x509_crq_t cert, int indx, + void *data, size_t * sizeof_data); + int gnutls_x509_crq_get_attribute_info (gnutls_x509_crq_t cert, int indx, + void *oid, size_t * sizeof_oid); + int gnutls_x509_crq_get_pk_algorithm (gnutls_x509_crq_t crq, unsigned int *bits); + + int gnutls_x509_crq_get_key_rsa_raw (gnutls_x509_crq_t crq, + gnutls_datum_t * m, + gnutls_datum_t * e); + + int gnutls_x509_crq_get_key_usage (gnutls_x509_crq_t cert, + unsigned int *key_usage, + unsigned int *critical); + int gnutls_x509_crq_get_basic_constraints (gnutls_x509_crq_t cert, + unsigned int *critical, + int *ca, int *pathlen); + int gnutls_x509_crq_get_subject_alt_name (gnutls_x509_crq_t cert, + unsigned int seq, void *ret, + size_t * ret_size, + unsigned int *ret_type, + unsigned int *critical); + int gnutls_x509_crq_get_subject_alt_othername_oid (gnutls_x509_crq_t cert, + unsigned int seq, + void *ret, size_t * ret_size); + + int gnutls_x509_crq_get_extension_by_oid (gnutls_x509_crq_t cert, + const char *oid, int indx, + void *buf, size_t * sizeof_buf, + unsigned int *critical); #ifdef __cplusplus } diff --git a/lib/x509/crl.c b/lib/x509/crl.c index 90658a87d9..11f4b18feb 100644 --- a/lib/x509/crl.c +++ b/lib/x509/crl.c @@ -937,7 +937,7 @@ gnutls_x509_crl_get_extension_info (gnutls_x509_crl_t crl, int indx, if (result == ASN1_ELEMENT_NOT_FOUND) return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; - else if (result < 0) + else if (result != ASN1_SUCCESS) { gnutls_assert (); return _gnutls_asn2err (result); @@ -947,7 +947,7 @@ gnutls_x509_crl_get_extension_info (gnutls_x509_crl_t crl, int indx, indx + 1); len = sizeof (str_critical); result = asn1_read_value (crl->crl, name, str_critical, &len); - if (result < 0) + if (result != ASN1_SUCCESS) { gnutls_assert (); return _gnutls_asn2err (result); diff --git a/lib/x509/crq.c b/lib/x509/crq.c index fc02c2f575..29ae0299a7 100644 --- a/lib/x509/crq.c +++ b/lib/x509/crq.c @@ -445,6 +445,167 @@ gnutls_x509_crq_get_challenge_password (gnutls_x509_crq_t crq, "1.2.840.113549.1.9.7", 0, 0, pass, sizeof_pass); } +/* This function will attempt to set the requested attribute in + * the given X509v3 certificate. + * + * Critical will be either 0 or 1. + */ +static int +add_attribute (ASN1_TYPE asn, const char* root, const char *attribute_id, + const gnutls_datum_t * ext_data) +{ + int result; + const char *str; + char name[MAX_NAME_SIZE]; + + snprintf (name, sizeof (name), "%s", root); + + /* Add a new attribute in the list. + */ + result = asn1_write_value (asn, name, "NEW", 1); + if (result != ASN1_SUCCESS) + { + gnutls_assert (); + return _gnutls_asn2err (result); + } + + snprintf (name, sizeof (name), "%s.?LAST.type", root); + + result = + asn1_write_value (asn, name, attribute_id, 1); + if (result != ASN1_SUCCESS) + { + gnutls_assert (); + return _gnutls_asn2err (result); + } + + snprintf (name, sizeof (name), "%s.?LAST.values", root); + + result = asn1_write_value (asn, name, "NEW", 1); + if (result != ASN1_SUCCESS) + { + gnutls_assert (); + return _gnutls_asn2err (result); + } + + snprintf (name, sizeof (name), "%s.?LAST.values.?LAST", root); + + result = + _gnutls_x509_write_value (asn, name, ext_data, 0); + if (result < 0) + { + gnutls_assert (); + return result; + } + + return 0; +} + +/* Overwrite the given attribute (using the index) + * index here starts from one. + */ +static int +overwrite_attribute (ASN1_TYPE asn, const char* root, unsigned int indx, + const gnutls_datum_t * ext_data) +{ + char name[MAX_NAME_SIZE], name2[MAX_NAME_SIZE]; + const char *str; + int result; + + snprintf (name, sizeof (name), "%s.?%u", root, indx); + + _gnutls_str_cpy (name2, sizeof (name2), name); + _gnutls_str_cat (name2, sizeof (name2), ".values.?LAST"); + + result = _gnutls_x509_write_value (asn, name2, ext_data, 0); + if (result < 0) + { + gnutls_assert (); + return result; + } + + return 0; +} + +static int +set_attribute (ASN1_TYPE asn, const char* root, + const char *ext_id, + const gnutls_datum_t * ext_data) +{ + int result; + int k, len; + char name[MAX_NAME_SIZE], name2[MAX_NAME_SIZE]; + char extnID[128]; + + /* Find the index of the given attribute. + */ + k = 0; + do + { + k++; + + snprintf (name, sizeof (name), "%s.?%u", root, k); + + len = sizeof (extnID) - 1; + result = asn1_read_value (asn, name, extnID, &len); + + /* move to next + */ + + if (result == ASN1_ELEMENT_NOT_FOUND) + { + break; + } + + do + { + + _gnutls_str_cpy (name2, sizeof (name2), name); + _gnutls_str_cat (name2, sizeof (name2), ".type"); + + len = sizeof (extnID) - 1; + result = asn1_read_value (asn, name2, extnID, &len); + + if (result == ASN1_ELEMENT_NOT_FOUND) + { + gnutls_assert (); + break; + } + else if (result != ASN1_SUCCESS) + { + gnutls_assert (); + return _gnutls_asn2err (result); + } + + /* Handle Extension + */ + if (strcmp (extnID, ext_id) == 0) + { + /* attribute was found + */ + return overwrite_attribute (asn, root, k, ext_data); + } + + + } + while (0); + } + while (1); + + if (result == ASN1_ELEMENT_NOT_FOUND) + { + return add_attribute (asn, root, ext_id, ext_data); + } + else + { + gnutls_assert (); + return _gnutls_asn2err (result); + } + + + return 0; +} + /** * gnutls_x509_crq_set_attribute_by_oid - This function will set an attribute in the request * @crq: should contain a gnutls_x509_crq_t structure @@ -465,6 +626,7 @@ gnutls_x509_crq_set_attribute_by_oid (gnutls_x509_crq_t crq, size_t sizeof_buf) { int result; + gnutls_datum data = {buf, sizeof_buf}; if (crq == NULL) { @@ -472,30 +634,8 @@ gnutls_x509_crq_set_attribute_by_oid (gnutls_x509_crq_t crq, return GNUTLS_E_INVALID_REQUEST; } - /* Add the attribute. - */ - result = - asn1_write_value (crq->crq, "certificationRequestInfo.attributes", - "NEW", 1); - if (result != ASN1_SUCCESS) - { - gnutls_assert (); - return _gnutls_asn2err (result); - } - - result = - _gnutls_x509_encode_and_write_attribute (oid, - crq->crq, - "certificationRequestInfo.attributes.?LAST", - buf, sizeof_buf, 1); - - if (result < 0) - { - gnutls_assert (); - return result; - } - - return 0; + return set_attribute (crq->crq, "certificationRequestInfo.attributes", + oid, &data); } /** @@ -677,6 +817,72 @@ gnutls_x509_crq_set_key (gnutls_x509_crq_t crq, gnutls_x509_privkey_t key) return 0; } +/** + * gnutls_x509_crq_get_key_rsa_raw - This function will export the RSA public key + * @crq: Holds the certificate + * @m: will hold the modulus + * @e: will hold the public exponent + * + * This function will export the RSA public key's parameters found in + * the given structure. The new parameters will be allocated using + * gnutls_malloc() and will be stored in the appropriate datum. + * + * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error. + **/ +int +gnutls_x509_crq_get_key_rsa_raw (gnutls_x509_crq_t crq, + gnutls_datum_t * m, gnutls_datum_t * e) +{ + int ret; + bigint_t params[MAX_PUBLIC_PARAMS_SIZE]; + int params_size = MAX_PUBLIC_PARAMS_SIZE; + int i; + + if (crq == NULL) + { + gnutls_assert (); + return GNUTLS_E_INVALID_REQUEST; + } + + ret = gnutls_x509_crq_get_pk_algorithm (crq, NULL); + if (ret != GNUTLS_PK_RSA) + { + gnutls_assert (); + return GNUTLS_E_INVALID_REQUEST; + } + + ret = _gnutls_x509_crq_get_mpis (crq, params, ¶ms_size); + if (ret < 0) + { + gnutls_assert (); + return ret; + } + + ret = _gnutls_mpi_dprint (params[0], m); + if (ret < 0) + { + gnutls_assert (); + goto cleanup; + } + + ret = _gnutls_mpi_dprint (params[1], e); + if (ret < 0) + { + gnutls_assert (); + _gnutls_free_datum (m); + goto cleanup; + } + + ret = 0; + +cleanup: + for (i = 0; i < params_size; i++) + { + _gnutls_mpi_release (¶ms[i]); + } + return ret; +} + /** * gnutls_x509_crq_set_key_rsa_raw - associate Certificate request with a key * @crq: should contain a #gnutls_x509_crq_t structure @@ -972,4 +1178,789 @@ gnutls_x509_crq_get_pk_algorithm (gnutls_x509_crq_t crq, unsigned int *bits) return result; } +/** + * gnutls_x509_crq_get_attribute_info - Get attribute id + * @cert: should contain a #gnutls_x509_crq_t structure + * @indx: Specifies which attribute OID to send. Use zero to get the first one. + * @oid: a pointer to a structure to hold the OID + * @sizeof_oid: initially holds the maximum size of @oid, on return + * holds actual size of @oid. + * + * This function will return the requested attribute OID in the + * certificate, and the critical flag for it. The attribute OID will + * be stored as a string in the provided buffer. Use + * gnutls_x509_crq_get_attribute_data() to extract the data. + * + * If the buffer provided is not long enough to hold the output, then + * *@sizeof_oid is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will be + * returned. + * + * Return 0 on success. A negative value may be returned in case of + * parsing error. If you have reached the last attribute available + * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned. + * + **/ +int +gnutls_x509_crq_get_attribute_info (gnutls_x509_crq_t cert, int indx, + void *oid, size_t * sizeof_oid) +{ + int result; + char str_critical[10]; + char name[MAX_NAME_SIZE]; + int len; + + if (!cert) + { + gnutls_assert (); + return GNUTLS_E_INVALID_REQUEST; + } + + snprintf (name, sizeof (name), "certificationRequestInfo.attributes.?%u.type", + indx + 1); + + len = *sizeof_oid; + result = asn1_read_value (cert->crq, name, oid, &len); + *sizeof_oid = len; + + if (result == ASN1_ELEMENT_NOT_FOUND) + return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; + else if (result < 0) + { + gnutls_assert (); + return _gnutls_asn2err (result); + } + + return 0; + +} + +/** + * gnutls_x509_crq_get_attribute_data - Get the specified attribute data + * @cert: should contain a #gnutls_x509_crq_t structure + * @indx: Specifies which attribute OID to send. Use zero to get the first one. + * @data: a pointer to a structure to hold the data (may be null) + * @sizeof_data: initially holds the size of @oid + * + * This function will return the requested attribute data in the + * certificate request. The attribute data will be stored as a string in the + * provided buffer. + * + * Use gnutls_x509_crq_get_attribute_info() to extract the OID. + * Use gnutls_x509_crq_get_attribute_by_oid() instead, + * if you want to get data indexed by the attribute OID rather than + * sequence. + * + * Return 0 on success. A negative value may be returned in case of + * parsing error. If you have reached the last attribute available + * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned. + **/ +int +gnutls_x509_crq_get_attribute_data (gnutls_x509_crq_t cert, int indx, + void *data, size_t * sizeof_data) +{ + int result, len; + char name[MAX_NAME_SIZE]; + + if (!cert) + { + gnutls_assert (); + return GNUTLS_E_INVALID_REQUEST; + } + + snprintf (name, sizeof (name), "certificationRequestInfo.attributes.?%u.values.?1", + indx + 1); + + len = *sizeof_data; + result = asn1_read_value (cert->crq, name, data, &len); + *sizeof_data = len; + + if (result == ASN1_ELEMENT_NOT_FOUND) + return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; + else if (result < 0) + { + gnutls_assert (); + return _gnutls_asn2err (result); + } + + return 0; +} + +/** + * gnutls_x509_crq_get_extension_info - Get extension id and criticality + * @cert: should contain a #gnutls_x509_crq_t structure + * @indx: Specifies which extension OID to send. Use zero to get the first one. + * @oid: a pointer to a structure to hold the OID + * @sizeof_oid: initially holds the maximum size of @oid, on return + * holds actual size of @oid. + * @critical: output variable with critical flag, may be NULL. + * + * This function will return the requested extension OID in the + * certificate, and the critical flag for it. The extension OID will + * be stored as a string in the provided buffer. Use + * gnutls_x509_crq_get_extension_data() to extract the data. + * + * If the buffer provided is not long enough to hold the output, then + * *@sizeof_oid is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will be + * returned. + * + * Return 0 on success. A negative value may be returned in case of + * parsing error. If you have reached the last extension available + * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned. + * + **/ +int +gnutls_x509_crq_get_extension_info (gnutls_x509_crq_t cert, int indx, + void *oid, size_t * sizeof_oid, + int *critical) +{ + int result; + char str_critical[10]; + char name[MAX_NAME_SIZE]; + unsigned char extensions[4*1024]; + size_t extensions_size = sizeof(extensions); + ASN1_TYPE c2; + int len; + + if (!cert) + { + gnutls_assert (); + return GNUTLS_E_INVALID_REQUEST; + } + + /* read extensionRequest */ + result = gnutls_x509_crq_get_attribute_by_oid (cert, "1.2.840.113549.1.9.14", + 0, extensions, &extensions_size); + if (result < 0) + { + gnutls_assert (); + return result; + } + + result = asn1_create_element + (_gnutls_get_pkix (), "PKIX1.Extensions", &c2); + if (result != ASN1_SUCCESS) + { + gnutls_assert (); + return _gnutls_asn2err (result); + } + + result = asn1_der_decoding (&c2, extensions, extensions_size, NULL); + if (result != ASN1_SUCCESS) + { + gnutls_assert (); + asn1_delete_structure (&c2); + return _gnutls_asn2err (result); + } + + snprintf (name, sizeof (name), "?%u.extnID", indx + 1); + + len = *sizeof_oid; + result = asn1_read_value (c2, name, oid, &len); + *sizeof_oid = len; + + if (result == ASN1_ELEMENT_NOT_FOUND) + { + asn1_delete_structure (&c2); + gnutls_assert(); + return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; + } + else if (result < 0) + { + gnutls_assert (); + asn1_delete_structure (&c2); + return _gnutls_asn2err (result); + } + + snprintf (name, sizeof (name), "?%u.critical", indx + 1); + len = sizeof (str_critical); + result = asn1_read_value (c2, name, str_critical, &len); + + asn1_delete_structure (&c2); + + if (result < 0) + { + gnutls_assert (); + return _gnutls_asn2err (result); + } + + if (critical) + { + if (str_critical[0] == 'T') + *critical = 1; + else + *critical = 0; + } + + return 0; + +} + +/** + * gnutls_x509_crq_get_extension_data - Get the specified extension data + * @cert: should contain a #gnutls_x509_crq_t structure + * @indx: Specifies which extension OID to send. Use zero to get the first one. + * @data: a pointer to a structure to hold the data (may be null) + * @sizeof_data: initially holds the size of @oid + * + * This function will return the requested extension data in the + * certificate. The extension data will be stored as a string in the + * provided buffer. + * + * Use gnutls_x509_crq_get_extension_info() to extract the OID and + * critical flag. Use gnutls_x509_crq_get_extension_by_oid() instead, + * if you want to get data indexed by the extension OID rather than + * sequence. + * + * Return 0 on success. A negative value may be returned in case of + * parsing error. If you have reached the last extension available + * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned. + **/ +int +gnutls_x509_crq_get_extension_data (gnutls_x509_crq_t cert, int indx, + void *data, size_t * sizeof_data) +{ + int result, len; + char name[MAX_NAME_SIZE]; + unsigned char extensions[4*1024]; + size_t extensions_size = sizeof(extensions); + ASN1_TYPE c2; + + if (!cert) + { + gnutls_assert (); + return GNUTLS_E_INVALID_REQUEST; + } + + /* read extensionRequest */ + result = gnutls_x509_crq_get_attribute_by_oid (cert, "1.2.840.113549.1.9.14", + 0, extensions, &extensions_size); + if (result < 0) + { + gnutls_assert (); + return result; + } + + result = asn1_create_element + (_gnutls_get_pkix (), "PKIX1.Extensions", &c2); + if (result != ASN1_SUCCESS) + { + gnutls_assert (); + return _gnutls_asn2err (result); + } + + result = asn1_der_decoding (&c2, extensions, extensions_size, NULL); + if (result != ASN1_SUCCESS) + { + gnutls_assert (); + asn1_delete_structure (&c2); + return _gnutls_asn2err (result); + } + + snprintf (name, sizeof (name), "?%u.extnValue", + indx + 1); + + len = *sizeof_data; + result = asn1_read_value (c2, name, data, &len); + *sizeof_data = len; + + asn1_delete_structure (&c2); + + if (result == ASN1_ELEMENT_NOT_FOUND) + return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; + else if (result < 0) + { + gnutls_assert (); + return _gnutls_asn2err (result); + } + + return 0; +} + +/** + * gnutls_x509_crq_get_key_usage - return the certificate's key usage + * @cert: should contain a #gnutls_x509_crq_t structure + * @key_usage: where the key usage bits will be stored + * @critical: will be non zero if the extension is marked as critical + * + * This function will return certificate's key usage, by reading the + * keyUsage X.509 extension (2.5.29.15). The key usage value will + * ORed values of the: %GNUTLS_KEY_DIGITAL_SIGNATURE, + * %GNUTLS_KEY_NON_REPUDIATION, %GNUTLS_KEY_KEY_ENCIPHERMENT, + * %GNUTLS_KEY_DATA_ENCIPHERMENT, %GNUTLS_KEY_KEY_AGREEMENT, + * %GNUTLS_KEY_KEY_CERT_SIGN, %GNUTLS_KEY_CRL_SIGN, + * %GNUTLS_KEY_ENCIPHER_ONLY, %GNUTLS_KEY_DECIPHER_ONLY. + * + * Returns: the certificate key usage, or a negative value in case of + * parsing error. If the certificate does not contain the keyUsage + * extension %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned. + * + **/ +int +gnutls_x509_crq_get_key_usage (gnutls_x509_crq_t cert, + unsigned int *key_usage, + unsigned int *critical) +{ + int result; + uint16_t _usage; + opaque buf[256]; + size_t buf_size = sizeof(buf); + + if (cert == NULL) + { + gnutls_assert (); + return GNUTLS_E_INVALID_REQUEST; + } + + result = gnutls_x509_crq_get_extension_by_oid(cert, "2.5.29.15", 0, + buf, &buf_size, critical); + if (result < 0) + { + gnutls_assert(); + return result; + } + + result = _gnutls_x509_ext_extract_keyUsage (&_usage, buf, buf_size); + + *key_usage = _usage; + + if (result < 0) + { + gnutls_assert (); + return result; + } + + return 0; +} + +/** + * gnutls_x509_crq_get_basic_constraints - This function returns the certificate basic constraints + * @cert: should contain a #gnutls_x509_crq_t structure + * @critical: will be non zero if the extension is marked as critical + * @ca: pointer to output integer indicating CA status, may be NULL, + * value is 1 if the certificate CA flag is set, 0 otherwise. + * @pathlen: pointer to output integer indicating path length (may be + * NULL), non-negative values indicate a present pathLenConstraint + * field and the actual value, -1 indicate that the field is absent. + * + * This function will read the certificate's basic constraints, and + * return the certificates CA status. It reads the basicConstraints + * X.509 extension (2.5.29.19). + * + * Return value: If the certificate is a CA a positive value will be + * returned, or zero if the certificate does not have CA flag set. A + * negative value may be returned in case of errors. If the + * certificate does not contain the basicConstraints extension + * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned. + **/ +int +gnutls_x509_crq_get_basic_constraints (gnutls_x509_crq_t cert, + unsigned int *critical, + int *ca, int *pathlen) +{ + int result; + int tmp_ca; + opaque buf[256]; + size_t buf_size = sizeof(buf); + + if (cert == NULL) + { + gnutls_assert (); + return GNUTLS_E_INVALID_REQUEST; + } + + result = gnutls_x509_crq_get_extension_by_oid(cert, "2.5.29.19", 0, + buf, &buf_size, critical); + if (result < 0) + { + gnutls_assert(); + return result; + } + + result = + _gnutls_x509_ext_extract_basicConstraints (&tmp_ca, + pathlen, + buf, buf_size); + if (ca) + *ca = tmp_ca; + + if (result < 0) + { + gnutls_assert (); + return result; + } + + return tmp_ca; +} + +static int +get_subject_alt_name (gnutls_x509_crq_t cert, + unsigned int seq, void *ret, + size_t * ret_size, unsigned int *ret_type, + unsigned int *critical, int othername_oid) +{ + int result; + ASN1_TYPE c2 = ASN1_TYPE_EMPTY; + gnutls_x509_subject_alt_name_t type; + opaque dnsname[2048]; + size_t dnsname_size = sizeof(dnsname); + + if (cert == NULL) + { + gnutls_assert (); + return GNUTLS_E_INVALID_REQUEST; + } + + if (ret) + memset (ret, 0, *ret_size); + else + *ret_size = 0; + + if ((result = + gnutls_x509_crq_get_extension_by_oid (cert, "2.5.29.17", 0, + dnsname, &dnsname_size, critical)) < 0) + { + gnutls_assert(); + return result; + } + + result = asn1_create_element + (_gnutls_get_pkix (), "PKIX1.SubjectAltName", &c2); + if (result != ASN1_SUCCESS) + { + gnutls_assert (); + return _gnutls_asn2err (result); + } + + result = asn1_der_decoding (&c2, dnsname, dnsname_size, NULL); + + if (result != ASN1_SUCCESS) + { + gnutls_assert (); + asn1_delete_structure (&c2); + return _gnutls_asn2err (result); + } + + result = + _gnutls_parse_general_name (c2, "", seq, ret, ret_size, ret_type, othername_oid); + + asn1_delete_structure (&c2); + + if (result < 0) + { + return result; + } + + type = result; + + return type; +} + +/** + * gnutls_x509_crq_get_subject_alt_name - Get certificate's alternative name, if any + * @cert: should contain a #gnutls_x509_crq_t structure + * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.) + * @ret: is the place where the alternative name will be copied to + * @ret_size: holds the size of ret. + * @ret_type: holds the type of the alternative name (one of gnutls_x509_subject_alt_name_t). + * @critical: will be non zero if the extension is marked as critical (may be null) + * + * This function will return the alternative names, contained in the + * given certificate. It is the same as gnutls_x509_crq_get_subject_alt_name() + * except for the fact that it will return the type of the alternative + * name in @ret_type even if the function fails for some reason (i.e. + * the buffer provided is not enough). + * + * The return values are the same as with gnutls_x509_crq_get_subject_alt_name(). + * + **/ +int +gnutls_x509_crq_get_subject_alt_name (gnutls_x509_crq_t cert, + unsigned int seq, void *ret, + size_t * ret_size, + unsigned int *ret_type, + unsigned int *critical) +{ + return get_subject_alt_name (cert ,seq, ret, ret_size, ret_type, critical, 0); +} + +/** + * gnutls_x509_crq_get_subject_alt_othername_oid - Get SAN otherName OID + * @cert: should contain a #gnutls_x509_crq_t structure + * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.) + * @ret: is the place where the otherName OID will be copied to + * @ret_size: holds the size of ret. + * + * This function will extract the type OID of an otherName Subject + * Alternative Name, contained in the given certificate, and return + * the type as an enumerated element. + * + * This function is only useful if + * gnutls_x509_crq_get_subject_alt_name() returned + * %GNUTLS_SAN_OTHERNAME. + * + * Returns: the alternative subject name type on success, one of the + * enumerated gnutls_x509_subject_alt_name_t. For supported OIDs, it + * will return one of the virtual (GNUTLS_SAN_OTHERNAME_*) types, + * e.g. %GNUTLS_SAN_OTHERNAME_XMPP, and %GNUTLS_SAN_OTHERNAME for + * unknown OIDs. It will return %GNUTLS_E_SHORT_MEMORY_BUFFER if + * @ret_size is not large enough to hold the value. In that case + * @ret_size will be updated with the required size. If the + * certificate does not have an Alternative name with the specified + * sequence number and with the otherName type then + * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned. + **/ +int +gnutls_x509_crq_get_subject_alt_othername_oid (gnutls_x509_crq_t cert, + unsigned int seq, + void *ret, size_t * ret_size) +{ + return get_subject_alt_name (cert, seq, ret, ret_size, NULL, NULL, 1); +} + +/** + * gnutls_x509_crq_get_extension_by_oid - This function returns the specified extension + * @cert: should contain a #gnutls_x509_crq_t structure + * @oid: holds an Object Identified in null terminated string + * @indx: In case multiple same OIDs exist in the extensions, this specifies which to send. Use zero to get the first one. + * @buf: a pointer to a structure to hold the name (may be null) + * @sizeof_buf: initially holds the size of @buf + * @critical: will be non zero if the extension is marked as critical + * + * This function will return the extension specified by the OID in the certificate. + * The extensions will be returned as binary data DER encoded, in the provided + * buffer. + * + * A negative value may be returned in case of parsing error. + * If the certificate does not contain the specified extension + * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned. + * + **/ +int +gnutls_x509_crq_get_extension_by_oid (gnutls_x509_crq_t cert, + const char *oid, int indx, + void *buf, size_t * sizeof_buf, + unsigned int *critical) +{ + int result; + gnutls_datum_t output; + unsigned int i; + char _oid[256]; + size_t oid_size; + + for (i=0;;i++) + { + oid_size = sizeof(_oid); + result = gnutls_x509_crq_get_extension_info ( cert, i, _oid, &oid_size, critical); + if (result < 0) + { + gnutls_assert(); + return result; + } + + if (strcmp( oid, _oid)==0) + { /* found */ + if (indx == 0) + return gnutls_x509_crq_get_extension_data (cert, i, buf, sizeof_buf); + else indx--; + } + } + + + return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; + +} + +/** + * gnutls_x509_crq_set_subject_alt_name - Set the subject Alternative Name + * @crq: a certificate of type #gnutls_x509_crq_t + * @type: is one of the gnutls_x509_subject_alt_name_t enumerations + * @data: The data to be set + * @data_size: The size of data to be set + * @flags: GNUTLS_FSAN_SET to clear previous data or GNUTLS_FSAN_APPEND to append. + * + * This function will set the subject alternative name certificate + * extension. It can set the following types: + * + * &GNUTLS_SAN_DNSNAME: as a text string + * + * &GNUTLS_SAN_RFC822NAME: as a text string + * + * &GNUTLS_SAN_URI: as a text string + * + * &GNUTLS_SAN_IPADDRESS: as a binary IP address (4 or 16 bytes) + * + * Other values can be set as binary values with the proper DER encoding. + * + * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a + * negative error value. + * + * Since: 2.6.0 + **/ +int +gnutls_x509_crq_set_subject_alt_name (gnutls_x509_crq_t crq, + gnutls_x509_subject_alt_name_t type, + const void *data, + unsigned int data_size, + unsigned int flags) +{ + int result = 0; + opaque tmp[4*1024]; + size_t tmp_size; + gnutls_datum_t der_data = { NULL, 0 }; + gnutls_datum_t prev_der_data; + unsigned int critical = 0; + + if (crq == NULL) + { + gnutls_assert (); + return GNUTLS_E_INVALID_REQUEST; + } + + /* Check if the extension already exists. + */ + + if (flags == GNUTLS_FSAN_APPEND) + { + tmp_size = sizeof(tmp); + result = gnutls_x509_crq_get_extension_by_oid (crq, "2.5.29.17", 0, + tmp, &tmp_size, &critical); + if (result < 0 && result != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) + { + gnutls_assert (); + return result; + } + } + + /* generate the extension. + */ + if (result < 0) + { + prev_der_data.data = NULL; + prev_der_data.size = 0; + } + else + { + prev_der_data.data = tmp; + prev_der_data.size = tmp_size; + } + + result = _gnutls_x509_ext_gen_subject_alt_name (type, data, data_size, + &prev_der_data, &der_data); + + if (result < 0) + { + gnutls_assert (); + goto finish; + } + + result = _gnutls_x509_crq_set_extension (crq, "2.5.29.17", &der_data, + critical); + + _gnutls_free_datum (&der_data); + + if (result < 0) + { + gnutls_assert (); + return result; + } + + return 0; + +finish: + return result; +} + +/** + * gnutls_x509_crq_set_basic_constraints - Set the basicConstraints extension + * @crq: a certificate of type #gnutls_x509_crq_t + * @ca: true(1) or false(0). Depending on the Certificate authority status. + * @pathLenConstraint: non-negative values indicate maximum length of path, + * and negative values indicate that the pathLenConstraints field should + * not be present. + * + * This function will set the basicConstraints certificate extension. + * + * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a + * negative error value. + **/ +int +gnutls_x509_crq_set_basic_constraints (gnutls_x509_crq_t crq, + unsigned int ca, int pathLenConstraint) +{ + int result; + gnutls_datum_t der_data; + + if (crq == NULL) + { + gnutls_assert (); + return GNUTLS_E_INVALID_REQUEST; + } + + /* generate the extension. + */ + result = _gnutls_x509_ext_gen_basicConstraints (ca, pathLenConstraint, + &der_data); + if (result < 0) + { + gnutls_assert (); + return result; + } + + result = _gnutls_x509_crq_set_extension (crq, "2.5.29.19", &der_data, 1); + + _gnutls_free_datum (&der_data); + + if (result < 0) + { + gnutls_assert (); + return result; + } + + return 0; +} + +/** + * gnutls_x509_crq_set_key_usage - Set the keyUsage extension + * @crq: a certificate of type #gnutls_x509_crq_t + * @usage: an ORed sequence of the GNUTLS_KEY_* elements. + * + * This function will set the keyUsage certificate extension. + * + * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a + * negative error value. + **/ +int +gnutls_x509_crq_set_key_usage (gnutls_x509_crq_t crq, unsigned int usage) +{ + int result; + gnutls_datum_t der_data; + + if (crq == NULL) + { + gnutls_assert (); + return GNUTLS_E_INVALID_REQUEST; + } + + /* generate the extension. + */ + result = _gnutls_x509_ext_gen_keyUsage ((uint16_t) usage, &der_data); + if (result < 0) + { + gnutls_assert (); + return result; + } + + result = _gnutls_x509_crq_set_extension (crq, "2.5.29.15", &der_data, 1); + + _gnutls_free_datum (&der_data); + + if (result < 0) + { + gnutls_assert (); + return result; + } + + return 0; +} + #endif /* ENABLE_PKI */ diff --git a/lib/x509/extensions.c b/lib/x509/extensions.c index a392887737..f84392a9c8 100644 --- a/lib/x509/extensions.c +++ b/lib/x509/extensions.c @@ -300,7 +300,7 @@ _gnutls_x509_crl_get_extension_oid (gnutls_x509_crl_t crl, * Critical will be either 0 or 1. */ static int -set_extension (ASN1_TYPE asn, const char* root, const char *extension_id, +add_extension (ASN1_TYPE asn, const char* root, const char *extension_id, const gnutls_datum_t * ext_data, unsigned int critical) { int result; @@ -318,7 +318,10 @@ set_extension (ASN1_TYPE asn, const char* root, const char *extension_id, return _gnutls_asn2err (result); } - snprintf (name, sizeof (name), "%s.?LAST.extnID", root); + if (root[0] != 0) + snprintf (name, sizeof (name), "%s.?LAST.extnID", root); + else + snprintf (name, sizeof (name), "?LAST.extnID"); result = asn1_write_value (asn, name, extension_id, 1); @@ -333,7 +336,10 @@ set_extension (ASN1_TYPE asn, const char* root, const char *extension_id, else str = "TRUE"; - snprintf (name, sizeof (name), "%s.?LAST.critical", root); + if (root[0] != 0) + snprintf (name, sizeof (name), "%s.?LAST.critical", root); + else + snprintf (name, sizeof (name), "?LAST.critical"); result = asn1_write_value (asn, name, str, 1); @@ -343,7 +349,10 @@ set_extension (ASN1_TYPE asn, const char* root, const char *extension_id, return _gnutls_asn2err (result); } - snprintf (name, sizeof (name), "%s.?LAST.extnValue", root); + if (root[0] != 0) + snprintf (name, sizeof (name), "%s.?LAST.extnValue", root); + else + snprintf (name, sizeof (name), "?LAST.extnValue"); result = _gnutls_x509_write_value (asn, name, ext_data, 0); @@ -367,7 +376,10 @@ overwrite_extension (ASN1_TYPE asn, const char* root, unsigned int indx, const char *str; int result; - snprintf (name, sizeof (name), "%s.?%u", root, indx); + if (root[0] != 0) + snprintf (name, sizeof (name), "%s.?%u", root, indx); + else + snprintf (name, sizeof (name), "?%u", indx); if (critical == 0) str = "FALSE"; @@ -397,13 +409,8 @@ overwrite_extension (ASN1_TYPE asn, const char* root, unsigned int indx, return 0; } -/* This function will attempt to overwrite the requested extension with - * the given one. - * - * Critical will be either 0 or 1. - */ -int -_gnutls_x509_crt_set_extension (gnutls_x509_crt_t cert, +static int +set_extension (ASN1_TYPE asn, const char* root, const char *ext_id, const gnutls_datum_t * ext_data, unsigned int critical) @@ -420,10 +427,13 @@ _gnutls_x509_crt_set_extension (gnutls_x509_crt_t cert, { k++; - snprintf (name, sizeof (name), "tbsCertificate.extensions.?%u", k); + if (root[0] != 0) + snprintf (name, sizeof (name), "%s.?%u", root, k); + else + snprintf (name, sizeof (name), "?%u", k); len = sizeof (extnID) - 1; - result = asn1_read_value (cert->cert, name, extnID, &len); + result = asn1_read_value (asn, name, extnID, &len); /* move to next */ @@ -440,7 +450,7 @@ _gnutls_x509_crt_set_extension (gnutls_x509_crt_t cert, _gnutls_str_cat (name2, sizeof (name2), ".extnID"); len = sizeof (extnID) - 1; - result = asn1_read_value (cert->cert, name2, extnID, &len); + result = asn1_read_value (asn, name2, extnID, &len); if (result == ASN1_ELEMENT_NOT_FOUND) { @@ -459,7 +469,7 @@ _gnutls_x509_crt_set_extension (gnutls_x509_crt_t cert, { /* extension was found */ - return overwrite_extension (cert->cert, "tbsCertificate.extensions", k, ext_data, critical); + return overwrite_extension (asn, root, k, ext_data, critical); } @@ -470,7 +480,7 @@ _gnutls_x509_crt_set_extension (gnutls_x509_crt_t cert, if (result == ASN1_ELEMENT_NOT_FOUND) { - return set_extension (cert->cert, "tbsCertificate.extensions", ext_id, ext_data, critical); + return add_extension (asn, root, ext_id, ext_data, critical); } else { @@ -482,86 +492,110 @@ _gnutls_x509_crt_set_extension (gnutls_x509_crt_t cert, return 0; } +/* This function will attempt to overwrite the requested extension with + * the given one. + * + * Critical will be either 0 or 1. + */ +int +_gnutls_x509_crt_set_extension (gnutls_x509_crt_t cert, + const char *ext_id, + const gnutls_datum_t * ext_data, + unsigned int critical) +{ + return set_extension( cert->cert, "tbsCertificate.extensions", ext_id, ext_data, critical); +} + int _gnutls_x509_crl_set_extension (gnutls_x509_crl_t crl, const char *ext_id, const gnutls_datum_t * ext_data, unsigned int critical) { + return set_extension( crl->crl, "tbsCertList.crlExtensions", ext_id, ext_data, critical); +} + +#ifdef ENABLE_PKI +int +_gnutls_x509_crq_set_extension (gnutls_x509_crq_t crq, + const char *ext_id, + const gnutls_datum_t * ext_data, + unsigned int critical) +{ + unsigned char extensions[4*1024]; + size_t extensions_size = sizeof(extensions); + gnutls_datum der; + ASN1_TYPE c2; int result; - int k, len; - char name[MAX_NAME_SIZE], name2[MAX_NAME_SIZE]; - char extnID[128]; - /* Find the index of the given extension. - */ - k = 0; - do + result = gnutls_x509_crq_get_attribute_by_oid (crq, "1.2.840.113549.1.9.14", + 0, extensions, &extensions_size); + if (result < 0) { - k++; - - snprintf (name, sizeof (name), "tbsCertList.crlExtensions.?%u", k); - - len = sizeof (extnID) - 1; - result = asn1_read_value (crl->crl, name, extnID, &len); - - /* move to next - */ - - if (result == ASN1_ELEMENT_NOT_FOUND) - { - break; - } - - do - { - - _gnutls_str_cpy (name2, sizeof (name2), name); - _gnutls_str_cat (name2, sizeof (name2), ".extnID"); + if (result == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) + { + extensions_size = 0; + } + else + { + gnutls_assert (); + return result; + } + } - len = sizeof (extnID) - 1; - result = asn1_read_value (crl->crl, name2, extnID, &len); + result = asn1_create_element + (_gnutls_get_pkix (), "PKIX1.Extensions", &c2); + if (result != ASN1_SUCCESS) + { + gnutls_assert (); + return _gnutls_asn2err (result); + } - if (result == ASN1_ELEMENT_NOT_FOUND) - { - gnutls_assert (); - break; - } - else if (result != ASN1_SUCCESS) - { - gnutls_assert (); - return _gnutls_asn2err (result); - } + if (extensions_size > 0) + { + result = asn1_der_decoding (&c2, extensions, extensions_size, NULL); + if (result != ASN1_SUCCESS) + { + gnutls_assert (); + asn1_delete_structure (&c2); + return _gnutls_asn2err (result); + } + } - /* Handle Extension - */ - if (strcmp (extnID, ext_id) == 0) - { - /* extension was found - */ - return overwrite_extension (crl->crl, "tbsCertList.crlExtensions", k, ext_data, critical); - } + result = set_extension( c2, "", ext_id, ext_data, critical); + if (result < 0) + { + gnutls_assert (); + asn1_delete_structure (&c2); + return result; + } + result = _gnutls_x509_der_encode (c2, "", &der, 0); - } - while (0); - } - while (1); + asn1_delete_structure (&c2); - if (result == ASN1_ELEMENT_NOT_FOUND) + if (result < 0) { - return set_extension (crl->crl, "tbsCertList.crlExtensions", ext_id, ext_data, critical); + gnutls_assert (); + return result; } - else + + result = gnutls_x509_crq_set_attribute_by_oid (crq, "1.2.840.113549.1.9.14", + der.data, der.size); + + _gnutls_free_datum( &der); + + if (result < 0) { gnutls_assert (); - return _gnutls_asn2err (result); + return result; } - + return 0; } +#endif /* Here we only extract the KeyUsage field, from the DER encoded * extension. diff --git a/lib/x509/mpi.c b/lib/x509/mpi.c index 9ae61ee70e..8af3af07bc 100644 --- a/lib/x509/mpi.c +++ b/lib/x509/mpi.c @@ -205,27 +205,23 @@ _gnutls_x509_read_dsa_pubkey (opaque * der, int dersize, bigint_t * params) /* Extracts DSA and RSA parameters from a certificate. */ -int -_gnutls_x509_crt_get_mpis (gnutls_x509_crt_t cert, +static int + get_mpis (int pk_algorithm, ASN1_TYPE asn, const char* root, bigint_t * params, int *params_size) { int result; - int pk_algorithm; + char name[256]; gnutls_datum tmp = { NULL, 0 }; - /* Read the algorithm's OID - */ - pk_algorithm = gnutls_x509_crt_get_pk_algorithm (cert, NULL); - /* Read the algorithm's parameters */ - result = _gnutls_x509_read_value (cert->cert, - "tbsCertificate.subjectPublicKeyInfo.subjectPublicKey", - &tmp, 2); + snprintf(name, sizeof(name), "%s.subjectPublicKey", root); + result = _gnutls_x509_read_value (asn, name, &tmp, 2); if (result < 0) { gnutls_assert (); + fprintf(stderr, "name: %s\n", name); return result; } @@ -278,9 +274,8 @@ _gnutls_x509_crt_get_mpis (gnutls_x509_crt_t cert, */ _gnutls_free_datum (&tmp); - result = _gnutls_x509_read_value (cert->cert, - "tbsCertificate.subjectPublicKeyInfo.algorithm.parameters", - &tmp, 0); + snprintf(name, sizeof(name), "%s.algorithm.parameters", root); + result = _gnutls_x509_read_value (asn, name, &tmp, 0); /* FIXME: If the parameters are not included in the certificate * then the issuer's parameters should be used. This is not @@ -319,6 +314,40 @@ error: return result; } +/* Extracts DSA and RSA parameters from a certificate. + */ +int +_gnutls_x509_crt_get_mpis (gnutls_x509_crt_t cert, + bigint_t * params, int *params_size) +{ + int result; + int pk_algorithm; + gnutls_datum tmp = { NULL, 0 }; + + /* Read the algorithm's OID + */ + pk_algorithm = gnutls_x509_crt_get_pk_algorithm (cert, NULL); + + return get_mpis( pk_algorithm, cert->cert, "tbsCertificate.subjectPublicKeyInfo", params, params_size); +} + +/* Extracts DSA and RSA parameters from a certificate. + */ +int +_gnutls_x509_crq_get_mpis (gnutls_x509_crq_t cert, + bigint_t * params, int *params_size) +{ + int result; + int pk_algorithm; + gnutls_datum tmp = { NULL, 0 }; + + /* Read the algorithm's OID + */ + pk_algorithm = gnutls_x509_crq_get_pk_algorithm (cert, NULL); + + return get_mpis( pk_algorithm, cert->crq, "certificationRequestInfo.subjectPKInfo", params, params_size); +} + /* * some x509 certificate functions that relate to MPI parameter * setting. This writes the BIT STRING subjectPublicKey. diff --git a/lib/x509/output.c b/lib/x509/output.c index 93497d8629..4451421484 100644 --- a/lib/x509/output.c +++ b/lib/x509/output.c @@ -209,6 +209,7 @@ print_ski (gnutls_string * str, gnutls_x509_crt_t cert) #define TYPE_CRL 1 #define TYPE_CRT 2 +#define TYPE_CRQ 3 static void print_aki (gnutls_string * str, int type, void* cert) @@ -219,8 +220,12 @@ print_aki (gnutls_string * str, int type, void* cert) if (type == TYPE_CRT) err = gnutls_x509_crt_get_authority_key_id (cert, buffer, &size, NULL); - else + else if (type == TYPE_CRL) err = gnutls_x509_crl_get_authority_key_id (cert, buffer, &size, NULL); + else { + gnutls_assert(); + return; + } if (err != GNUTLS_E_SHORT_MEMORY_BUFFER) { @@ -255,12 +260,18 @@ print_aki (gnutls_string * str, int type, void* cert) } static void -print_key_usage (gnutls_string * str, gnutls_x509_crt_t cert) +print_key_usage (gnutls_string * str, const char* prefix, int type, void* cert) { unsigned int key_usage; int err; - err = gnutls_x509_crt_get_key_usage (cert, &key_usage, NULL); + if (type == TYPE_CRT) + err = gnutls_x509_crt_get_key_usage (cert, &key_usage, NULL); + else if (type == TYPE_CRQ) + err = gnutls_x509_crq_get_key_usage (cert, &key_usage, NULL); + else + return; + if (err < 0) { addf (str, "error: get_key_usage: %s\n", gnutls_strerror (err)); @@ -268,23 +279,23 @@ print_key_usage (gnutls_string * str, gnutls_x509_crt_t cert) } if (key_usage & GNUTLS_KEY_DIGITAL_SIGNATURE) - addf (str, _("\t\t\tDigital signature.\n")); + addf (str, _("%s\t\t\tDigital signature.\n"), prefix); if (key_usage & GNUTLS_KEY_NON_REPUDIATION) - addf (str, _("\t\t\tNon repudiation.\n")); + addf (str, _("%s\t\t\tNon repudiation.\n"), prefix); if (key_usage & GNUTLS_KEY_KEY_ENCIPHERMENT) - addf (str, _("\t\t\tKey encipherment.\n")); + addf (str, _("%s\t\t\tKey encipherment.\n"), prefix); if (key_usage & GNUTLS_KEY_DATA_ENCIPHERMENT) - addf (str, _("\t\t\tData encipherment.\n")); + addf (str, _("%s\t\t\tData encipherment.\n"), prefix); if (key_usage & GNUTLS_KEY_KEY_AGREEMENT) - addf (str, _("\t\t\tKey agreement.\n")); + addf (str, _("%s\t\t\tKey agreement.\n"), prefix); if (key_usage & GNUTLS_KEY_KEY_CERT_SIGN) - addf (str, _("\t\t\tCertificate signing.\n")); + addf (str, _("%s\t\t\tCertificate signing.\n"), prefix); if (key_usage & GNUTLS_KEY_CRL_SIGN) - addf (str, _("\t\t\tCRL signing.\n")); + addf (str, _("%s\t\t\tCRL signing.\n"), prefix); if (key_usage & GNUTLS_KEY_ENCIPHER_ONLY) - addf (str, _("\t\t\tKey encipher only.\n")); + addf (str, _("%s\t\t\tKey encipher only.\n"), prefix); if (key_usage & GNUTLS_KEY_DECIPHER_ONLY) - addf (str, _("\t\t\tKey decipher only.\n")); + addf (str, _("%s\t\t\tKey decipher only.\n"), prefix); } #ifdef ENABLE_PKI @@ -423,12 +434,17 @@ print_key_purpose (gnutls_string * str, gnutls_x509_crt_t cert) #endif static void -print_basic (gnutls_string * str, gnutls_x509_crt_t cert) +print_basic (gnutls_string * str, const char* prefix, int type, void* cert) { int pathlen; int err; - err = gnutls_x509_crt_get_basic_constraints (cert, NULL, NULL, &pathlen); + if (type == TYPE_CRT) + err = gnutls_x509_crt_get_basic_constraints (cert, NULL, NULL, &pathlen); + else if (type == TYPE_CRQ) + err = gnutls_x509_crq_get_basic_constraints (cert, NULL, NULL, &pathlen); + else return; + if (err < 0) { addf (str, "error: get_basic_constraints: %s\n", gnutls_strerror (err)); @@ -436,17 +452,17 @@ print_basic (gnutls_string * str, gnutls_x509_crt_t cert) } if (err == 0) - addf (str, _("\t\t\tCertificate Authority (CA): FALSE\n")); + addf (str, _("%s\t\t\tCertificate Authority (CA): FALSE\n"), prefix); else - addf (str, _("\t\t\tCertificate Authority (CA): TRUE\n")); + addf (str, _("%s\t\t\tCertificate Authority (CA): TRUE\n"), prefix); if (pathlen >= 0) - addf (str, _("\t\t\tPath Length Constraint: %d\n"), pathlen); + addf (str, _("%s\t\t\tPath Length Constraint: %d\n"), prefix, pathlen); } static void -print_san (gnutls_string * str, gnutls_x509_crt_t cert) +print_san (gnutls_string * str, const char* prefix, int type, void* cert) { unsigned int san_idx; char str_ip[64]; @@ -458,9 +474,14 @@ print_san (gnutls_string * str, gnutls_x509_crt_t cert) size_t size = 0; int err; - err = - gnutls_x509_crt_get_subject_alt_name (cert, san_idx, buffer, &size, + if (type == TYPE_CRT) + err = gnutls_x509_crt_get_subject_alt_name (cert, san_idx, buffer, &size, NULL); + else if (type == TYPE_CRQ) + err = gnutls_x509_crq_get_subject_alt_name (cert, san_idx, buffer, &size, + NULL, NULL); + else return; + if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) break; if (err != GNUTLS_E_SHORT_MEMORY_BUFFER) @@ -477,8 +498,13 @@ print_san (gnutls_string * str, gnutls_x509_crt_t cert) return; } - err = gnutls_x509_crt_get_subject_alt_name (cert, san_idx, - buffer, &size, NULL); + if (type == TYPE_CRT) + err = gnutls_x509_crt_get_subject_alt_name (cert, san_idx, buffer, &size, + NULL); + else if (type == TYPE_CRQ) + err = gnutls_x509_crq_get_subject_alt_name (cert, san_idx, buffer, &size, + NULL, NULL); + if (err < 0) { gnutls_free (buffer); @@ -490,23 +516,23 @@ print_san (gnutls_string * str, gnutls_x509_crt_t cert) switch (err) { case GNUTLS_SAN_DNSNAME: - addf (str, "\t\t\tDNSname: %.*s\n", size, buffer); + addf (str, "%s\t\t\tDNSname: %.*s\n", prefix, size, buffer); break; case GNUTLS_SAN_RFC822NAME: - addf (str, "\t\t\tRFC822name: %.*s\n", size, buffer); + addf (str, "%s\t\t\tRFC822name: %.*s\n", prefix, size, buffer); break; case GNUTLS_SAN_URI: - addf (str, "\t\t\tURI: %.*s\n", size, buffer); + addf (str, "%s\t\t\tURI: %.*s\n", prefix, size, buffer); break; case GNUTLS_SAN_IPADDRESS: p = ip_to_string(buffer, size, str_ip, sizeof(str_ip)); if (p == NULL) p = ERROR_STR; - addf (str, "\t\t\tIPAddress: %s\n", p); + addf (str, "%s\t\t\tIPAddress: %s\n", prefix, p); break; case GNUTLS_SAN_DN: - addf (str, "\t\t\tdirectoryName: %.*s\n", size, buffer); + addf (str, "%s\t\t\tdirectoryName: %.*s\n", prefix, size, buffer); break; case GNUTLS_SAN_OTHERNAME: @@ -515,8 +541,13 @@ print_san (gnutls_string * str, gnutls_x509_crt_t cert) size_t oidsize; oidsize = 0; - err = gnutls_x509_crt_get_subject_alt_othername_oid + if (type == TYPE_CRT) + err = gnutls_x509_crt_get_subject_alt_othername_oid + (cert, san_idx, oid, &oidsize); + else if (type == TYPE_CRQ) + err = gnutls_x509_crq_get_subject_alt_othername_oid (cert, san_idx, oid, &oidsize); + if (err != GNUTLS_E_SHORT_MEMORY_BUFFER) { gnutls_free (buffer); @@ -533,7 +564,11 @@ print_san (gnutls_string * str, gnutls_x509_crt_t cert) return; } - err = gnutls_x509_crt_get_subject_alt_othername_oid + if (type == TYPE_CRT) + err = gnutls_x509_crt_get_subject_alt_othername_oid + (cert, san_idx, oid, &oidsize); + else if (type == TYPE_CRQ) + err = gnutls_x509_crq_get_subject_alt_othername_oid (cert, san_idx, oid, &oidsize); if (err < 0) { @@ -545,13 +580,13 @@ print_san (gnutls_string * str, gnutls_x509_crt_t cert) } if (err == GNUTLS_SAN_OTHERNAME_XMPP) - addf (str, _("\t\t\tXMPP Address: %.*s\n"), size, buffer); + addf (str, _("%s\t\t\tXMPP Address: %.*s\n"), prefix, size, buffer); else { - addf (str, _("\t\t\totherName OID: %.*s\n"), oidsize, oid); - addf (str, _("\t\t\totherName DER: ")); + addf (str, _("%s\t\t\totherName OID: %.*s\n"), prefix, oidsize, oid); + addf (str, _("%s\t\t\totherName DER: "), prefix); hexprint (str, buffer, size); - addf (str, _("\n\t\t\totherName ASCII: ")); + addf (str, _("\n%s\t\t\totherName ASCII: "), prefix); asciiprint (str, buffer, size); addf (str, "\n"); } @@ -568,170 +603,9 @@ print_san (gnutls_string * str, gnutls_x509_crt_t cert) } } -static void -print_cert (gnutls_string * str, gnutls_x509_crt_t cert, int notsigned) +void print_extensions( gnutls_string * str, const char* prefix, int type, void* cert) { - /* Version. */ - { - int version = gnutls_x509_crt_get_version (cert); - if (version < 0) - addf (str, "error: get_version: %s\n", gnutls_strerror (version)); - else - addf (str, _("\tVersion: %d\n"), version); - } - - /* Serial. */ - { - char serial[128]; - size_t serial_size = sizeof (serial); - int err; - - err = gnutls_x509_crt_get_serial (cert, serial, &serial_size); - if (err < 0) - addf (str, "error: get_serial: %s\n", gnutls_strerror (err)); - else - { - addf (str, _("\tSerial Number (hex): ")); - hexprint (str, serial, serial_size); - addf (str, "\n"); - } - } - - /* Issuer. */ - if (!notsigned) - { - char dn[1024]; - size_t dn_size = sizeof (dn); - int err; - - err = gnutls_x509_crt_get_issuer_dn (cert, dn, &dn_size); - if (err < 0) - addf (str, "error: get_issuer_dn: %s\n", gnutls_strerror (err)); - else - addf (str, _("\tIssuer: %s\n"), dn); - } - - /* Validity. */ - { - time_t tim; - - addf (str, _("\tValidity:\n")); - - tim = gnutls_x509_crt_get_activation_time (cert); - { - char s[42]; - size_t max = sizeof (s); - struct tm t; - - if (gmtime_r (&tim, &t) == NULL) - addf (str, "error: gmtime_r (%d)\n", t); - else if (strftime (s, max, "%a %b %d %H:%M:%S UTC %Y", &t) == 0) - addf (str, "error: strftime (%d)\n", t); - else - addf (str, _("\t\tNot Before: %s\n"), s); - } - - tim = gnutls_x509_crt_get_expiration_time (cert); - { - char s[42]; - size_t max = sizeof (s); - struct tm t; - - if (gmtime_r (&tim, &t) == NULL) - addf (str, "error: gmtime_r (%d)\n", t); - else if (strftime (s, max, "%a %b %d %H:%M:%S UTC %Y", &t) == 0) - addf (str, "error: strftime (%d)\n", t); - else - addf (str, _("\t\tNot After: %s\n"), s); - } - } - - /* Subject. */ - { - char dn[1024]; - size_t dn_size = sizeof (dn); - int err; - - err = gnutls_x509_crt_get_dn (cert, dn, &dn_size); - if (err < 0) - addf (str, "error: get_dn: %s\n", gnutls_strerror (err)); - else - addf (str, _("\tSubject: %s\n"), dn); - } - - /* SubjectPublicKeyInfo. */ - { - int err; - unsigned int bits; - - err = gnutls_x509_crt_get_pk_algorithm (cert, &bits); - if (err < 0) - addf (str, "error: get_pk_algorithm: %s\n", gnutls_strerror (err)); - else - { - const char *name = gnutls_pk_algorithm_get_name (err); - if (name == NULL) - name = _("unknown"); - - addf (str, _("\tSubject Public Key Algorithm: %s\n"), name); -#ifdef ENABLE_PKI - switch (err) - { - case GNUTLS_PK_RSA: - { - gnutls_datum_t m, e; - - err = gnutls_x509_crt_get_pk_rsa_raw (cert, &m, &e); - if (err < 0) - addf (str, "error: get_pk_rsa_raw: %s\n", - gnutls_strerror (err)); - else - { - addf (str, _("\t\tModulus (bits %d):\n"), bits); - hexdump (str, m.data, m.size, "\t\t\t"); - addf (str, _("\t\tExponent:\n")); - hexdump (str, e.data, e.size, "\t\t\t"); - } - - gnutls_free (m.data); - gnutls_free (e.data); - } - break; - - case GNUTLS_PK_DSA: - { - gnutls_datum_t p, q, g, y; - - err = gnutls_x509_crt_get_pk_dsa_raw (cert, &p, &q, &g, &y); - if (err < 0) - addf (str, "error: get_pk_dsa_raw: %s\n", - gnutls_strerror (err)); - else - { - addf (str, _("\t\tPublic key (bits %d):\n"), bits); - hexdump (str, y.data, y.size, "\t\t\t"); - addf (str, _("\t\tP:\n")); - hexdump (str, p.data, p.size, "\t\t\t"); - addf (str, _("\t\tQ:\n")); - hexdump (str, q.data, q.size, "\t\t\t"); - addf (str, _("\t\tG:\n")); - hexdump (str, g.data, g.size, "\t\t\t"); - } - } - break; - - default: - break; - } -#endif - } - } - - /* Extensions. */ - if (gnutls_x509_crt_get_version (cert) >= 3) - { - size_t i; - int err = 0; +int i, err; for (i = 0;; i++) { @@ -747,9 +621,19 @@ print_cert (gnutls_string * str, gnutls_x509_crt_t cert, int notsigned) size_t aki_idx = 0; size_t crldist_idx = 0; - err = gnutls_x509_crt_get_extension_info (cert, i, + if (type == TYPE_CRT) + err = gnutls_x509_crt_get_extension_info (cert, i, oid, &sizeof_oid, &critical); + else if (type == TYPE_CRQ) + err = gnutls_x509_crq_get_extension_info (cert, i, + oid, &sizeof_oid, + &critical); + else { + gnutls_assert(); + return; + } + if (err < 0) { if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) @@ -760,7 +644,7 @@ print_cert (gnutls_string * str, gnutls_x509_crt_t cert, int notsigned) } if (i == 0) - addf (str, _("\tExtensions:\n")); + addf (str, _("%s\tExtensions:\n"), prefix); if (strcmp (oid, "2.5.29.19") == 0) { @@ -770,10 +654,10 @@ print_cert (gnutls_string * str, gnutls_x509_crt_t cert, int notsigned) continue; } - addf (str, _("\t\tBasic Constraints (%s):\n"), + addf (str, _("%s\t\tBasic Constraints (%s):\n"), prefix, critical ? _("critical") : _("not critical")); - print_basic (str, cert); + print_basic (str, prefix, type, cert); basic_idx++; } @@ -785,10 +669,10 @@ print_cert (gnutls_string * str, gnutls_x509_crt_t cert, int notsigned) continue; } - addf (str, _("\t\tSubject Key Identifier (%s):\n"), + addf (str, _("%s\t\tSubject Key Identifier (%s):\n"), prefix, critical ? _("critical") : _("not critical")); - print_ski (str, cert); + if (type == TYPE_CRT) print_ski (str, cert); ski_idx++; } @@ -800,10 +684,10 @@ print_cert (gnutls_string * str, gnutls_x509_crt_t cert, int notsigned) continue; } - addf (str, _("\t\tAuthority Key Identifier (%s):\n"), + addf (str, _("%s\t\tAuthority Key Identifier (%s):\n"), prefix, critical ? _("critical") : _("not critical")); - print_aki (str, TYPE_CRT, cert); + if (type == TYPE_CRT) print_aki (str, TYPE_CRT, cert); aki_idx++; } @@ -815,10 +699,10 @@ print_cert (gnutls_string * str, gnutls_x509_crt_t cert, int notsigned) continue; } - addf (str, _("\t\tKey Usage (%s):\n"), + addf (str, _("%s\t\tKey Usage (%s):\n"), prefix, critical ? _("critical") : _("not critical")); - print_key_usage (str, cert); + print_key_usage (str, prefix, type, cert); keyusage_idx++; } @@ -830,11 +714,11 @@ print_cert (gnutls_string * str, gnutls_x509_crt_t cert, int notsigned) continue; } - addf (str, _("\t\tKey Purpose (%s):\n"), + addf (str, _("%s\t\tKey Purpose (%s):\n"), prefix, critical ? _("critical") : _("not critical")); #ifdef ENABLE_PKI - print_key_purpose (str, cert); + if (type == TYPE_CRT) print_key_purpose (str, cert); #endif keypurpose_idx++; @@ -847,10 +731,10 @@ print_cert (gnutls_string * str, gnutls_x509_crt_t cert, int notsigned) continue; } - addf (str, _("\t\tSubject Alternative Name (%s):\n"), + addf (str, _("%s\t\tSubject Alternative Name (%s):\n"), prefix, critical ? _("critical") : _("not critical")); - print_san (str, cert); + print_san (str, prefix, type, cert); san_idx++; } @@ -862,11 +746,11 @@ print_cert (gnutls_string * str, gnutls_x509_crt_t cert, int notsigned) continue; } - addf (str, _("\t\tCRL Distribution points (%s):\n"), + addf (str, _("%s\t\tCRL Distribution points (%s):\n"), prefix, critical ? _("critical") : _("not critical")); #ifdef ENABLE_PKI - print_crldist (str, cert); + if (type == TYPE_CRT) print_crldist (str, cert); #endif crldist_idx++; @@ -879,58 +763,243 @@ print_cert (gnutls_string * str, gnutls_x509_crt_t cert, int notsigned) continue; } - addf (str, _("\t\tProxy Certificate Information (%s):\n"), + addf (str, _("%s\t\tProxy Certificate Information (%s):\n"), prefix, + critical ? _("critical") : _("not critical")); + + if (type == TYPE_CRT) print_proxy (str, cert); + + proxy_idx++; + } + else + { + char *buffer; + size_t extlen = 0; + + addf (str, _("%s\t\tUnknown extension %s (%s):\n"), oid, prefix, critical ? _("critical") : _("not critical")); - print_proxy (str, cert); + if (type == TYPE_CRT) + err = gnutls_x509_crt_get_extension_data (cert, i, NULL, &extlen); + else if (type == TYPE_CRQ) + err = gnutls_x509_crq_get_extension_data (cert, i, NULL, &extlen); + else { + gnutls_assert(); + return; + } + + if (err < 0) + { + addf (str, "error: get_extension_data: %s\n", + gnutls_strerror (err)); + continue; + } + + buffer = gnutls_malloc (extlen); + if (!buffer) + { + addf (str, "error: malloc: %s\n", gnutls_strerror (err)); + continue; + } + + if (type == TYPE_CRT) + err = gnutls_x509_crt_get_extension_data (cert, i, buffer, &extlen); + else if (type == TYPE_CRQ) + err = gnutls_x509_crq_get_extension_data (cert, i, buffer, &extlen); + + if (err < 0) + { + gnutls_free (buffer); + addf (str, "error: get_extension_data2: %s\n", + gnutls_strerror (err)); + continue; + } + + addf (str, _("%s\t\t\tASCII: "), prefix); + asciiprint (str, buffer, extlen); + addf (str, "\n"); + + addf (str, _("%s\t\t\tHexdump: "), prefix); + hexprint (str, buffer, extlen); + adds (str, "\n"); + + gnutls_free (buffer); + } + } +} + +static void +print_cert (gnutls_string * str, gnutls_x509_crt_t cert, int notsigned) +{ + /* Version. */ + { + int version = gnutls_x509_crt_get_version (cert); + if (version < 0) + addf (str, "error: get_version: %s\n", gnutls_strerror (version)); + else + addf (str, _("\tVersion: %d\n"), version); + } + + /* Serial. */ + { + char serial[128]; + size_t serial_size = sizeof (serial); + int err; + + err = gnutls_x509_crt_get_serial (cert, serial, &serial_size); + if (err < 0) + addf (str, "error: get_serial: %s\n", gnutls_strerror (err)); + else + { + addf (str, _("\tSerial Number (hex): ")); + hexprint (str, serial, serial_size); + addf (str, "\n"); + } + } + + /* Issuer. */ + if (!notsigned) + { + char dn[1024]; + size_t dn_size = sizeof (dn); + int err; + + err = gnutls_x509_crt_get_issuer_dn (cert, dn, &dn_size); + if (err < 0) + addf (str, "error: get_issuer_dn: %s\n", gnutls_strerror (err)); + else + addf (str, _("\tIssuer: %s\n"), dn); + } + + /* Validity. */ + { + time_t tim; + + addf (str, _("\tValidity:\n")); + + tim = gnutls_x509_crt_get_activation_time (cert); + { + char s[42]; + size_t max = sizeof (s); + struct tm t; + + if (gmtime_r (&tim, &t) == NULL) + addf (str, "error: gmtime_r (%d)\n", t); + else if (strftime (s, max, "%a %b %d %H:%M:%S UTC %Y", &t) == 0) + addf (str, "error: strftime (%d)\n", t); + else + addf (str, _("\t\tNot Before: %s\n"), s); + } + + tim = gnutls_x509_crt_get_expiration_time (cert); + { + char s[42]; + size_t max = sizeof (s); + struct tm t; + + if (gmtime_r (&tim, &t) == NULL) + addf (str, "error: gmtime_r (%d)\n", t); + else if (strftime (s, max, "%a %b %d %H:%M:%S UTC %Y", &t) == 0) + addf (str, "error: strftime (%d)\n", t); + else + addf (str, _("\t\tNot After: %s\n"), s); + } + } + + /* Subject. */ + { + char dn[1024]; + size_t dn_size = sizeof (dn); + int err; + + err = gnutls_x509_crt_get_dn (cert, dn, &dn_size); + if (err < 0) + addf (str, "error: get_dn: %s\n", gnutls_strerror (err)); + else + addf (str, _("\tSubject: %s\n"), dn); + } + + /* SubjectPublicKeyInfo. */ + { + int err; + unsigned int bits; + + err = gnutls_x509_crt_get_pk_algorithm (cert, &bits); + if (err < 0) + addf (str, "error: get_pk_algorithm: %s\n", gnutls_strerror (err)); + else + { + const char *name = gnutls_pk_algorithm_get_name (err); + if (name == NULL) + name = _("unknown"); + + addf (str, _("\tSubject Public Key Algorithm: %s\n"), name); +#ifdef ENABLE_PKI + switch (err) + { + case GNUTLS_PK_RSA: + { + gnutls_datum_t m, e; + + err = gnutls_x509_crt_get_pk_rsa_raw (cert, &m, &e); + if (err < 0) + addf (str, "error: get_pk_rsa_raw: %s\n", + gnutls_strerror (err)); + else + { + addf (str, _("\t\tModulus (bits %d):\n"), bits); + hexdump (str, m.data, m.size, "\t\t\t"); + addf (str, _("\t\tExponent:\n")); + hexdump (str, e.data, e.size, "\t\t\t"); + + gnutls_free (m.data); + gnutls_free (e.data); + } - proxy_idx++; } - else - { - char *buffer; - size_t extlen = 0; + break; - addf (str, _("\t\tUnknown extension %s (%s):\n"), oid, - critical ? _("critical") : _("not critical")); + case GNUTLS_PK_DSA: + { + gnutls_datum_t p, q, g, y; - err = gnutls_x509_crt_get_extension_data (cert, i, - NULL, &extlen); + err = gnutls_x509_crt_get_pk_dsa_raw (cert, &p, &q, &g, &y); if (err < 0) + addf (str, "error: get_pk_dsa_raw: %s\n", + gnutls_strerror (err)); + else { - addf (str, "error: get_extension_data: %s\n", - gnutls_strerror (err)); - continue; - } + addf (str, _("\t\tPublic key (bits %d):\n"), bits); + hexdump (str, y.data, y.size, "\t\t\t"); + addf (str, _("\t\tP:\n")); + hexdump (str, p.data, p.size, "\t\t\t"); + addf (str, _("\t\tQ:\n")); + hexdump (str, q.data, q.size, "\t\t\t"); + addf (str, _("\t\tG:\n")); + hexdump (str, g.data, g.size, "\t\t\t"); - buffer = gnutls_malloc (extlen); - if (!buffer) - { - addf (str, "error: malloc: %s\n", gnutls_strerror (err)); - continue; - } + gnutls_free (p.data); + gnutls_free (q.data); + gnutls_free (g.data); + gnutls_free (y.data); - err = gnutls_x509_crt_get_extension_data (cert, i, - buffer, &extlen); - if (err < 0) - { - gnutls_free (buffer); - addf (str, "error: get_extension_data2: %s\n", - gnutls_strerror (err)); - continue; } + } + break; - addf (str, _("\t\t\tASCII: ")); - asciiprint (str, buffer, extlen); - addf (str, "\n"); + default: + break; + } +#endif + } + } - addf (str, _("\t\t\tHexdump: ")); - hexprint (str, buffer, extlen); - adds (str, "\n"); + /* Extensions. */ + if (gnutls_x509_crt_get_version (cert) >= 3) + { + size_t i; + int err = 0; - gnutls_free (buffer); - } - } + print_extensions( str, "", TYPE_CRT, cert); } /* Signature. */ @@ -1551,4 +1620,242 @@ gnutls_x509_crl_print (gnutls_x509_crl_t crl, return 0; } +static void +print_crq (gnutls_string * str, gnutls_x509_crq_t cert) +{ + /* Version. */ + { + int version = gnutls_x509_crq_get_version (cert); + if (version < 0) + addf (str, "error: get_version: %s\n", gnutls_strerror (version)); + else + addf (str, _("\tVersion: %d\n"), version); + } + + /* Subject */ + { + char dn[1024]; + size_t dn_size = sizeof (dn); + int err; + + err = gnutls_x509_crq_get_dn (cert, dn, &dn_size); + if (err < 0) + addf (str, "error: get_dn: %s\n", gnutls_strerror (err)); + else + addf (str, _("\tSubject: %s\n"), dn); + } + + /* SubjectPublicKeyInfo. */ + { + int err; + unsigned int bits; + + err = gnutls_x509_crq_get_pk_algorithm (cert, &bits); + if (err < 0) + addf (str, "error: get_pk_algorithm: %s\n", gnutls_strerror (err)); + else + { + const char *name = gnutls_pk_algorithm_get_name (err); + if (name == NULL) + name = _("unknown"); + + addf (str, _("\tSubject Public Key Algorithm: %s\n"), name); + switch (err) + { + case GNUTLS_PK_RSA: + { + gnutls_datum_t m, e; + + err = gnutls_x509_crq_get_key_rsa_raw (cert, &m, &e); + if (err < 0) + addf (str, "error: get_pk_rsa_raw: %s\n", + gnutls_strerror (err)); + else + { + addf (str, _("\t\tModulus (bits %d):\n"), bits); + hexdump (str, m.data, m.size, "\t\t\t"); + addf (str, _("\t\tExponent:\n")); + hexdump (str, e.data, e.size, "\t\t\t"); + + gnutls_free (m.data); + gnutls_free (e.data); + } + + } + break; +#if 0 /* not implemented yet */ + case GNUTLS_PK_DSA: + { + gnutls_datum_t p, q, g, y; + + err = gnutls_x509_crq_get_key_dsa_raw (cert, &p, &q, &g, &y); + if (err < 0) + addf (str, "error: get_pk_dsa_raw: %s\n", + gnutls_strerror (err)); + else + { + addf (str, _("\t\tPublic key (bits %d):\n"), bits); + hexdump (str, y.data, y.size, "\t\t\t"); + addf (str, _("\t\tP:\n")); + hexdump (str, p.data, p.size, "\t\t\t"); + addf (str, _("\t\tQ:\n")); + hexdump (str, q.data, q.size, "\t\t\t"); + addf (str, _("\t\tG:\n")); + hexdump (str, g.data, g.size, "\t\t\t"); + + gnutls_free (p.data); + gnutls_free (q.data); + gnutls_free (g.data); + gnutls_free (y.data); + + } + } + break; +#endif + default: + break; + } + } + } + + /* parse attributes */ + { + size_t i; + int err = 0; + + for (i = 0;; i++) + { + char oid[128] = ""; + size_t sizeof_oid = sizeof (oid); + int critical; + int extensions = 0; + int challenge = 0; + + err = gnutls_x509_crq_get_attribute_info (cert, i, + oid, &sizeof_oid); + if (err < 0) + { + if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) + break; + addf (str, "error: get_extension_info: %s\n", + gnutls_strerror (err)); + continue; + } + + if (i == 0) + addf (str, _("\tAttributes:\n")); + + if (strcmp (oid, "1.2.840.113549.1.9.14") == 0) + { + if (extensions) + { + addf (str, "error: more than one extensionsRequest\n"); + continue; + } + + print_extensions (str, "\t", TYPE_CRQ, cert); + + extensions++; + } + else if (strcmp (oid, "1.2.840.113549.1.9.7") == 0) + { + char pass[1024]; + size_t pass_size = sizeof (pass); + int err; + + if (challenge) + { + addf (str, "error: more than one Challenge password attribute\n"); + continue; + } + + err = gnutls_x509_crq_get_challenge_password (cert, pass, &pass_size); + if (err < 0) + addf (str, "error: get_challenge_password: %s\n", gnutls_strerror (err)); + else + addf (str, _("\t\tChallenge password: %s\n"), pass); + + challenge++; + } + else + { + char *buffer; + size_t extlen = 0; + + addf (str, _("\t\tUnknown attribute %s:\n"), oid); + + err = gnutls_x509_crq_get_attribute_data (cert, i, + NULL, &extlen); + if (err < 0) + { + addf (str, "error: get_attribute_data: %s\n", + gnutls_strerror (err)); + continue; + } + + buffer = gnutls_malloc (extlen); + if (!buffer) + { + addf (str, "error: malloc: %s\n", gnutls_strerror (err)); + continue; + } + + err = gnutls_x509_crq_get_attribute_data (cert, i, + buffer, &extlen); + if (err < 0) + { + gnutls_free (buffer); + addf (str, "error: get_attribute_data2: %s\n", + gnutls_strerror (err)); + continue; + } + + addf (str, _("\t\t\tASCII: ")); + asciiprint (str, buffer, extlen); + addf (str, "\n"); + + addf (str, _("\t\t\tHexdump: ")); + hexprint (str, buffer, extlen); + adds (str, "\n"); + + gnutls_free (buffer); + } + } + } +} + +/** + * gnutls_x509_crq_print - Pretty print PKCS 10 certificate request + * @cert: The structure to be printed + * @format: Indicate the format to use + * @out: Newly allocated datum with zero terminated string. + * + * This function will pretty print a certificate request, suitable for + * display to a human. + * + * The output @out needs to be deallocate using gnutls_free(). + * + * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a + * negative error value. + **/ +int +gnutls_x509_crq_print (gnutls_x509_crq_t crq, + gnutls_certificate_print_formats_t format, + gnutls_datum_t * out) +{ + gnutls_string str; + + _gnutls_string_init (&str, gnutls_malloc, gnutls_realloc, gnutls_free); + + _gnutls_string_append_str (&str, _("PKCS #10 Certificate Request Information:\n")); + + print_crq (&str, crq); + + _gnutls_string_append_data (&str, "\0", 1); + out->data = str.data; + out->size = strlen (str.data); + + return 0; +} + #endif /* ENABLE_PKI */ diff --git a/lib/x509/x509.c b/lib/x509/x509.c index 8be70e1053..707ca81c0f 100644 --- a/lib/x509/x509.c +++ b/lib/x509/x509.c @@ -904,8 +904,8 @@ is_type_printable (int type) /* returns the type and the name on success. * Type is also returned as a parameter in case of an error. */ -static int -parse_general_name (ASN1_TYPE src, const char *src_name, +int +_gnutls_parse_general_name (ASN1_TYPE src, const char *src_name, int seq, void *name, size_t * name_size, unsigned int *ret_type, int othername_oid) { @@ -1132,12 +1132,13 @@ get_subject_alt_name (gnutls_x509_crt_t cert, } result = - parse_general_name (c2, "", seq, ret, ret_size, ret_type, othername_oid); + _gnutls_parse_general_name (c2, "", seq, ret, ret_size, ret_type, othername_oid); asn1_delete_structure (&c2); if (result < 0) { + gnutls_assert(); return result; } @@ -1618,7 +1619,7 @@ gnutls_x509_crt_get_extension_info (gnutls_x509_crt_t cert, int indx, if (result == ASN1_ELEMENT_NOT_FOUND) return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; - else if (result < 0) + else if (result != ASN1_SUCCESS) { gnutls_assert (); return _gnutls_asn2err (result); @@ -1628,7 +1629,7 @@ gnutls_x509_crt_get_extension_info (gnutls_x509_crt_t cert, int indx, indx + 1); len = sizeof (str_critical); result = asn1_read_value (cert->cert, name, str_critical, &len); - if (result < 0) + if (result != ASN1_SUCCESS) { gnutls_assert (); return _gnutls_asn2err (result); @@ -2437,7 +2438,7 @@ gnutls_x509_crt_get_crl_dist_points (gnutls_x509_crt_t cert, */ _gnutls_str_cpy (name, sizeof (name), "?1.distributionPoint.fullName"); - result = parse_general_name (c2, name, seq, ret, ret_size, NULL, 0); + result = _gnutls_parse_general_name (c2, name, seq, ret, ret_size, NULL, 0); if (result < 0) { asn1_delete_structure (&c2); diff --git a/lib/x509/x509_int.h b/lib/x509/x509_int.h index 074bac0720..cd921c3693 100644 --- a/lib/x509/x509_int.h +++ b/lib/x509/x509_int.h @@ -161,6 +161,10 @@ int _gnutls_x509_get_dn_oid (ASN1_TYPE asn1_struct, const char *asn1_rdn_name, int indx, void *_oid, size_t * sizeof_oid); +int _gnutls_parse_general_name (ASN1_TYPE src, const char *src_name, + int seq, void *name, size_t * name_size, + unsigned int *ret_type, int othername_oid); + /* dsa.c */ @@ -247,7 +251,9 @@ int _gnutls_x509_ext_gen_proxyCertInfo (int pathLenConstraint, gnutls_datum_t * der_ext); /* mpi.c */ - +int _gnutls_x509_crq_get_mpis (gnutls_x509_crq_t cert, + bigint_t * params, int *params_size); + int _gnutls_x509_crt_get_mpis (gnutls_x509_crt_t cert, bigint_t * params, int *params_size); int _gnutls_x509_read_rsa_params (opaque * der, int dersize, bigint_t * params); @@ -348,4 +354,10 @@ int _pkcs12_decode_crt_bag (gnutls_pkcs12_bag_type_t type, int _pkcs12_encode_crt_bag (gnutls_pkcs12_bag_type_t type, const gnutls_datum_t * raw, gnutls_datum_t * out); +/* crq */ +int _gnutls_x509_crq_set_extension (gnutls_x509_crq_t crq, + const char *ext_id, + const gnutls_datum_t * ext_data, + unsigned int critical); + #endif diff --git a/src/certtool-cfg.c b/src/certtool-cfg.c index bbc05c28aa..ec9fb459ee 100644 --- a/src/certtool-cfg.c +++ b/src/certtool-cfg.c @@ -37,6 +37,7 @@ /* Gnulib portability files. */ #include #include "readline.h" +#include "certtool-common.h" extern int batch; @@ -772,7 +773,7 @@ static int string_to_ip( unsigned char *ip, const char * str) } void -get_ip_addr_set (gnutls_x509_crt_t crt) +get_ip_addr_set (int type, void* crt) { int ret, i; unsigned char ip[16]; @@ -791,7 +792,11 @@ get_ip_addr_set (gnutls_x509_crt_t crt) exit(1); } - ret = gnutls_x509_crt_set_subject_alt_name( crt, GNUTLS_SAN_IPADDRESS, + if (type == TYPE_CRT) + ret = gnutls_x509_crt_set_subject_alt_name( crt, GNUTLS_SAN_IPADDRESS, + ip, len, GNUTLS_FSAN_APPEND); + else + ret = gnutls_x509_crq_set_subject_alt_name( crt, GNUTLS_SAN_IPADDRESS, ip, len, GNUTLS_FSAN_APPEND); if (ret < 0) break; @@ -801,15 +806,20 @@ get_ip_addr_set (gnutls_x509_crt_t crt) { const char *p; - p = read_str ("Enter the dnsName of the subject of the certificate: "); + p = read_str ("Enter the IP address of the subject of the certificate: "); if (!p) return; - len = string_to_ip( ip, cfg.ip_addr[i]); + len = string_to_ip( ip, p); if (len <= 0) { fprintf(stderr, "Error parsing address: %s\n", cfg.ip_addr[i]); exit(1); } - ret = gnutls_x509_crt_set_subject_alt_name( crt, GNUTLS_SAN_IPADDRESS, + + if (type == TYPE_CRT) + ret = gnutls_x509_crt_set_subject_alt_name( crt, GNUTLS_SAN_IPADDRESS, + ip, len, GNUTLS_FSAN_APPEND); + else + ret = gnutls_x509_crq_set_subject_alt_name( crt, GNUTLS_SAN_IPADDRESS, ip, len, GNUTLS_FSAN_APPEND); } @@ -822,7 +832,7 @@ get_ip_addr_set (gnutls_x509_crt_t crt) void -get_email_set (gnutls_x509_crt_t crt) +get_email_set (int type, void* crt) { int ret, i; @@ -833,8 +843,12 @@ get_email_set (gnutls_x509_crt_t crt) for (i = 0; cfg.email[i] != NULL; i ++) { - ret = gnutls_x509_crt_set_subject_alt_name( crt, GNUTLS_SAN_RFC822NAME, - cfg.email[i], strlen(cfg.email[i]), GNUTLS_FSAN_APPEND); + if (type == TYPE_CRT) + ret = gnutls_x509_crt_set_subject_alt_name( crt, GNUTLS_SAN_RFC822NAME, + cfg.email[i], strlen(cfg.email[i]), GNUTLS_FSAN_APPEND); + else + ret = gnutls_x509_crq_set_subject_alt_name( crt, GNUTLS_SAN_RFC822NAME, + cfg.email[i], strlen(cfg.email[i]), GNUTLS_FSAN_APPEND); if (ret < 0) break; } @@ -846,8 +860,12 @@ get_email_set (gnutls_x509_crt_t crt) p = read_str ("Enter the e-mail of the subject of the certificate: "); if (!p) return; - ret = gnutls_x509_crt_set_subject_alt_name( crt, GNUTLS_SAN_RFC822NAME, - p, strlen(p), GNUTLS_FSAN_APPEND); + if (type == TYPE_CRT) + ret = gnutls_x509_crt_set_subject_alt_name( crt, GNUTLS_SAN_RFC822NAME, + p, strlen(p), GNUTLS_FSAN_APPEND); + else + ret = gnutls_x509_crq_set_subject_alt_name( crt, GNUTLS_SAN_RFC822NAME, + p, strlen(p), GNUTLS_FSAN_APPEND); } if (ret < 0) @@ -858,7 +876,7 @@ get_email_set (gnutls_x509_crt_t crt) } void -get_dns_name_set (gnutls_x509_crt_t crt) +get_dns_name_set (int type, void* crt) { int ret, i; @@ -869,8 +887,12 @@ get_dns_name_set (gnutls_x509_crt_t crt) for (i = 0; cfg.dns_name[i] != NULL; i ++) { - ret = gnutls_x509_crt_set_subject_alt_name( crt, GNUTLS_SAN_DNSNAME, - cfg.dns_name[i], strlen(cfg.dns_name[i]), GNUTLS_FSAN_APPEND); + if (type == TYPE_CRT) + ret = gnutls_x509_crt_set_subject_alt_name( crt, GNUTLS_SAN_DNSNAME, + cfg.dns_name[i], strlen(cfg.dns_name[i]), GNUTLS_FSAN_APPEND); + else + ret = gnutls_x509_crq_set_subject_alt_name( crt, GNUTLS_SAN_DNSNAME, + cfg.dns_name[i], strlen(cfg.dns_name[i]), GNUTLS_FSAN_APPEND); if (ret < 0) break; } @@ -882,8 +904,12 @@ get_dns_name_set (gnutls_x509_crt_t crt) p = read_str ("Enter the dnsName of the subject of the certificate: "); if (!p) return; - ret = gnutls_x509_crt_set_subject_alt_name( crt, GNUTLS_SAN_DNSNAME, - p, strlen(p), GNUTLS_FSAN_APPEND); + if (type == TYPE_CRT) + ret = gnutls_x509_crt_set_subject_alt_name( crt, GNUTLS_SAN_DNSNAME, + p, strlen(p), GNUTLS_FSAN_APPEND); + else + ret = gnutls_x509_crq_set_subject_alt_name( crt, GNUTLS_SAN_DNSNAME, + p, strlen(p), GNUTLS_FSAN_APPEND); } if (ret < 0) diff --git a/src/certtool-cfg.h b/src/certtool-cfg.h index 5fa6be45dd..1820b6799b 100644 --- a/src/certtool-cfg.h +++ b/src/certtool-cfg.h @@ -50,9 +50,9 @@ int get_crl_sign_status (void); int get_cert_sign_status (void); int get_encrypt_status (int server); int get_sign_status (int server); -void get_ip_addr_set (gnutls_x509_crt_t crt); -void get_dns_name_set (gnutls_x509_crt_t crt); -void get_email_set (gnutls_x509_crt_t crt); +void get_ip_addr_set (int type, void* crt); +void get_dns_name_set (int type, void* crt); +void get_email_set (int type, void* crt); void get_cn_crq_set (gnutls_x509_crq_t crq); diff --git a/src/certtool-common.h b/src/certtool-common.h new file mode 100644 index 0000000000..468e2cdca6 --- /dev/null +++ b/src/certtool-common.h @@ -0,0 +1,28 @@ +enum { + ACTION_SELF_SIGNED, + ACTION_GENERATE_PRIVKEY, + ACTION_CERT_INFO, + ACTION_GENERATE_REQUEST, + ACTION_GENERATE_CERTIFICATE, + ACTION_VERIFY_CHAIN, + ACTION_PRIVKEY_INFO, + ACTION_UPDATE_CERTIFICATE, + ACTION_TO_PKCS12, + ACTION_PKCS12_INFO, + ACTION_GENERATE_DH, + ACTION_GET_DH, + ACTION_CRL_INFO, + ACTION_P7_INFO, + ACTION_GENERATE_CRL, + ACTION_VERIFY_CRL, + ACTION_SMIME_TO_P7, + ACTION_GENERATE_PROXY, + ACTION_GENERATE_PKCS8, + ACTION_PGP_INFO, + ACTION_PGP_PRIVKEY_INFO, + ACTION_RING_INFO, + ACTION_REQUEST +}; + +#define TYPE_CRT 1 +#define TYPE_CRQ 2 diff --git a/src/certtool-gaa.c b/src/certtool-gaa.c index 2633f3208c..5a218f8e72 100644 --- a/src/certtool-gaa.c +++ b/src/certtool-gaa.c @@ -13,6 +13,8 @@ void certtool_version(void); +#include "certtool-common.h" + #include #include #include @@ -150,6 +152,7 @@ void gaa_help(void) __gaa_helpsingle(0, "pgp-certificate-info", "", "Print information on a OpenPGP certificate."); __gaa_helpsingle(0, "pgp-ring-info", "", "Print information on a keyring structure."); __gaa_helpsingle('l', "crl-info", "", "Print information on a CRL."); + __gaa_helpsingle(0, "crq-info", "", "Print information on a Certificate Request."); __gaa_helpsingle(0, "p12-info", "", "Print information on a PKCS #12 structure."); __gaa_helpsingle(0, "p7-info", "", "Print information on a PKCS #7 structure."); __gaa_helpsingle(0, "smime-to-p7", "", "Convert S/MIME to PKCS #7 structure."); @@ -189,49 +192,49 @@ typedef struct _gaainfo gaainfo; struct _gaainfo { -#line 123 "certtool.gaa" +#line 127 "certtool.gaa" int debug; -#line 119 "certtool.gaa" +#line 123 "certtool.gaa" char *template; -#line 116 "certtool.gaa" +#line 120 "certtool.gaa" char *infile; -#line 113 "certtool.gaa" +#line 117 "certtool.gaa" char *outfile; -#line 110 "certtool.gaa" +#line 114 "certtool.gaa" int quick_random; -#line 107 "certtool.gaa" +#line 111 "certtool.gaa" int bits; -#line 103 "certtool.gaa" +#line 107 "certtool.gaa" int outcert_format; -#line 99 "certtool.gaa" +#line 103 "certtool.gaa" int incert_format; -#line 96 "certtool.gaa" +#line 100 "certtool.gaa" int export; -#line 93 "certtool.gaa" +#line 97 "certtool.gaa" char *hash; -#line 90 "certtool.gaa" +#line 94 "certtool.gaa" int dsa; -#line 87 "certtool.gaa" +#line 91 "certtool.gaa" int pkcs8; -#line 80 "certtool.gaa" +#line 84 "certtool.gaa" int v1_cert; -#line 77 "certtool.gaa" +#line 81 "certtool.gaa" int fix_key; -#line 54 "certtool.gaa" +#line 56 "certtool.gaa" char *pass; -#line 51 "certtool.gaa" +#line 53 "certtool.gaa" char *ca; -#line 48 "certtool.gaa" +#line 50 "certtool.gaa" char *ca_privkey; -#line 45 "certtool.gaa" +#line 47 "certtool.gaa" char *cert; -#line 42 "certtool.gaa" +#line 44 "certtool.gaa" char *request; -#line 39 "certtool.gaa" +#line 41 "certtool.gaa" char *privkey; -#line 17 "certtool.gaa" +#line 19 "certtool.gaa" int action; -#line 16 "certtool.gaa" +#line 18 "certtool.gaa" int privkey_op; #line 114 "gaa.skel" @@ -287,7 +290,7 @@ static int gaa_error = 0; #define GAA_MULTIPLE_OPTION 3 #define GAA_REST 0 -#define GAA_NB_OPTION 46 +#define GAA_NB_OPTION 47 #define GAAOPTID_version 1 #define GAAOPTID_help 2 #define GAAOPTID_debug 3 @@ -313,27 +316,28 @@ static int gaa_error = 0; #define GAAOPTID_smime_to_p7 23 #define GAAOPTID_p7_info 24 #define GAAOPTID_p12_info 25 -#define GAAOPTID_crl_info 26 -#define GAAOPTID_pgp_ring_info 27 -#define GAAOPTID_pgp_certificate_info 28 -#define GAAOPTID_certificate_info 29 -#define GAAOPTID_password 30 -#define GAAOPTID_load_ca_certificate 31 -#define GAAOPTID_load_ca_privkey 32 -#define GAAOPTID_load_certificate 33 -#define GAAOPTID_load_request 34 -#define GAAOPTID_load_privkey 35 -#define GAAOPTID_get_dh_params 36 -#define GAAOPTID_generate_dh_params 37 -#define GAAOPTID_verify_crl 38 -#define GAAOPTID_verify_chain 39 -#define GAAOPTID_generate_request 40 -#define GAAOPTID_generate_privkey 41 -#define GAAOPTID_update_certificate 42 -#define GAAOPTID_generate_crl 43 -#define GAAOPTID_generate_proxy 44 -#define GAAOPTID_generate_certificate 45 -#define GAAOPTID_generate_self_signed 46 +#define GAAOPTID_crq_info 26 +#define GAAOPTID_crl_info 27 +#define GAAOPTID_pgp_ring_info 28 +#define GAAOPTID_pgp_certificate_info 29 +#define GAAOPTID_certificate_info 30 +#define GAAOPTID_password 31 +#define GAAOPTID_load_ca_certificate 32 +#define GAAOPTID_load_ca_privkey 33 +#define GAAOPTID_load_certificate 34 +#define GAAOPTID_load_request 35 +#define GAAOPTID_load_privkey 36 +#define GAAOPTID_get_dh_params 37 +#define GAAOPTID_generate_dh_params 38 +#define GAAOPTID_verify_crl 39 +#define GAAOPTID_verify_chain 40 +#define GAAOPTID_generate_request 41 +#define GAAOPTID_generate_privkey 42 +#define GAAOPTID_update_certificate 43 +#define GAAOPTID_generate_crl 44 +#define GAAOPTID_generate_proxy 45 +#define GAAOPTID_generate_certificate 46 +#define GAAOPTID_generate_self_signed 47 #line 168 "gaa.skel" @@ -493,12 +497,31 @@ static int gaa_getint(char *arg) return tmp; } +static char gaa_getchar(char *arg) +{ + if(strlen(arg) != 1) + { + printf("Option %s: '%s' isn't an character\n", gaa_current_option, arg); + GAAERROR(-1); + } + return arg[0]; +} static char* gaa_getstr(char *arg) { return arg; } - +static float gaa_getfloat(char *arg) +{ + float tmp; + char a; + if(sscanf(arg, "%f%c", &tmp, &a) < 1) + { + printf("Option %s: '%s' isn't a float number\n", gaa_current_option, arg); + GAAERROR(-1); + } + return tmp; +} /* option structures */ struct GAAOPTION_debug @@ -635,6 +658,7 @@ static int gaa_get_option_num(char *str, int status) GAA_CHECK1STR("", GAAOPTID_smime_to_p7); GAA_CHECK1STR("", GAAOPTID_p7_info); GAA_CHECK1STR("", GAAOPTID_p12_info); + GAA_CHECK1STR("", GAAOPTID_crq_info); GAA_CHECK1STR("l", GAAOPTID_crl_info); GAA_CHECK1STR("", GAAOPTID_pgp_ring_info); GAA_CHECK1STR("", GAAOPTID_pgp_certificate_info); @@ -679,6 +703,7 @@ static int gaa_get_option_num(char *str, int status) GAA_CHECKSTR("smime-to-p7", GAAOPTID_smime_to_p7); GAA_CHECKSTR("p7-info", GAAOPTID_p7_info); GAA_CHECKSTR("p12-info", GAAOPTID_p12_info); + GAA_CHECKSTR("crq-info", GAAOPTID_crq_info); GAA_CHECKSTR("crl-info", GAAOPTID_crl_info); GAA_CHECKSTR("pgp-ring-info", GAAOPTID_pgp_ring_info); GAA_CHECKSTR("pgp-certificate-info", GAAOPTID_pgp_certificate_info); @@ -746,14 +771,14 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) { case GAAOPTID_version: OK = 0; -#line 128 "certtool.gaa" +#line 132 "certtool.gaa" { certtool_version(); exit(0); ;}; return GAA_OK; break; case GAAOPTID_help: OK = 0; -#line 126 "certtool.gaa" +#line 130 "certtool.gaa" { gaa_help(); exit(0); ;}; return GAA_OK; @@ -763,7 +788,7 @@ static 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 124 "certtool.gaa" +#line 128 "certtool.gaa" { gaaval->debug = GAATMP_debug.arg1 ;}; return GAA_OK; @@ -773,7 +798,7 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) GAA_TESTMOREARGS; GAA_FILL(GAATMP_template.arg1, gaa_getstr, GAATMP_template.size1); gaa_index++; -#line 120 "certtool.gaa" +#line 124 "certtool.gaa" { gaaval->template = GAATMP_template.arg1 ;}; return GAA_OK; @@ -783,7 +808,7 @@ static 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 117 "certtool.gaa" +#line 121 "certtool.gaa" { gaaval->infile = GAATMP_infile.arg1 ;}; return GAA_OK; @@ -793,14 +818,14 @@ static 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 114 "certtool.gaa" +#line 118 "certtool.gaa" { gaaval->outfile = GAATMP_outfile.arg1 ;}; return GAA_OK; break; case GAAOPTID_disable_quick_random: OK = 0; -#line 111 "certtool.gaa" +#line 115 "certtool.gaa" { gaaval->quick_random = 0; ;}; return GAA_OK; @@ -810,42 +835,42 @@ static 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 108 "certtool.gaa" +#line 112 "certtool.gaa" { gaaval->bits = GAATMP_bits.arg1 ;}; return GAA_OK; break; case GAAOPTID_outraw: OK = 0; -#line 105 "certtool.gaa" +#line 109 "certtool.gaa" { gaaval->outcert_format=1 ;}; return GAA_OK; break; case GAAOPTID_outder: OK = 0; -#line 104 "certtool.gaa" +#line 108 "certtool.gaa" { gaaval->outcert_format=1 ;}; return GAA_OK; break; case GAAOPTID_inraw: OK = 0; -#line 101 "certtool.gaa" +#line 105 "certtool.gaa" { gaaval->incert_format=1 ;}; return GAA_OK; break; case GAAOPTID_inder: OK = 0; -#line 100 "certtool.gaa" +#line 104 "certtool.gaa" { gaaval->incert_format=1 ;}; return GAA_OK; break; case GAAOPTID_export_ciphers: OK = 0; -#line 97 "certtool.gaa" +#line 101 "certtool.gaa" { gaaval->export=1 ;}; return GAA_OK; @@ -855,113 +880,120 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) GAA_TESTMOREARGS; GAA_FILL(GAATMP_hash.arg1, gaa_getstr, GAATMP_hash.size1); gaa_index++; -#line 94 "certtool.gaa" +#line 98 "certtool.gaa" { gaaval->hash = GAATMP_hash.arg1 ;}; return GAA_OK; break; case GAAOPTID_dsa: OK = 0; -#line 91 "certtool.gaa" +#line 95 "certtool.gaa" { gaaval->dsa=1 ;}; return GAA_OK; break; case GAAOPTID_pkcs8: OK = 0; -#line 88 "certtool.gaa" +#line 92 "certtool.gaa" { gaaval->pkcs8=1 ;}; return GAA_OK; break; case GAAOPTID_to_p8: OK = 0; -#line 85 "certtool.gaa" -{ gaaval->action = 18; ;}; +#line 89 "certtool.gaa" +{ gaaval->action = ACTION_GENERATE_PKCS8; ;}; return GAA_OK; break; case GAAOPTID_to_p12: OK = 0; -#line 83 "certtool.gaa" -{ gaaval->action = 8; ;}; +#line 87 "certtool.gaa" +{ gaaval->action = ACTION_TO_PKCS12; ;}; return GAA_OK; break; case GAAOPTID_v1: OK = 0; -#line 81 "certtool.gaa" +#line 85 "certtool.gaa" { gaaval->v1_cert = 1; ;}; return GAA_OK; break; case GAAOPTID_fix_key: OK = 0; -#line 78 "certtool.gaa" +#line 82 "certtool.gaa" { gaaval->privkey_op=1; gaaval->fix_key = 1; ;}; return GAA_OK; break; case GAAOPTID_pgp_key_info: OK = 0; -#line 75 "certtool.gaa" -{ gaaval->privkey_op=1; gaaval->action = 20; ;}; +#line 79 "certtool.gaa" +{ gaaval->privkey_op=1; gaaval->action = ACTION_PGP_PRIVKEY_INFO; ;}; return GAA_OK; break; case GAAOPTID_key_info: OK = 0; -#line 73 "certtool.gaa" -{ gaaval->privkey_op=1; gaaval->action = 6; ;}; +#line 77 "certtool.gaa" +{ gaaval->privkey_op=1; gaaval->action = ACTION_PRIVKEY_INFO; ;}; return GAA_OK; break; case GAAOPTID_smime_to_p7: OK = 0; -#line 69 "certtool.gaa" -{ gaaval->action = 15; ;}; +#line 73 "certtool.gaa" +{ gaaval->action = ACTION_SMIME_TO_P7; ;}; return GAA_OK; break; case GAAOPTID_p7_info: OK = 0; -#line 67 "certtool.gaa" -{ gaaval->action = 12; ;}; +#line 71 "certtool.gaa" +{ gaaval->action = ACTION_P7_INFO; ;}; return GAA_OK; break; case GAAOPTID_p12_info: OK = 0; -#line 65 "certtool.gaa" -{ gaaval->action = 9; ;}; +#line 69 "certtool.gaa" +{ gaaval->action = ACTION_PKCS12_INFO; ;}; + + return GAA_OK; + break; + case GAAOPTID_crq_info: + OK = 0; +#line 67 "certtool.gaa" +{ gaaval->action = ACTION_REQUEST; ;}; return GAA_OK; break; case GAAOPTID_crl_info: OK = 0; -#line 63 "certtool.gaa" -{ gaaval->action = 11; ;}; +#line 65 "certtool.gaa" +{ gaaval->action = ACTION_CRL_INFO; ;}; return GAA_OK; break; case GAAOPTID_pgp_ring_info: OK = 0; -#line 61 "certtool.gaa" -{ gaaval->action = 21; ;}; +#line 63 "certtool.gaa" +{ gaaval->action = ACTION_RING_INFO; ;}; return GAA_OK; break; case GAAOPTID_pgp_certificate_info: OK = 0; -#line 59 "certtool.gaa" -{ gaaval->action = 19; ;}; +#line 61 "certtool.gaa" +{ gaaval->action = ACTION_PGP_INFO; ;}; return GAA_OK; break; case GAAOPTID_certificate_info: OK = 0; -#line 57 "certtool.gaa" -{ gaaval->action = 2; ;}; +#line 59 "certtool.gaa" +{ gaaval->action = ACTION_CERT_INFO; ;}; return GAA_OK; break; @@ -970,7 +1002,7 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) GAA_TESTMOREARGS; GAA_FILL(GAATMP_password.arg1, gaa_getstr, GAATMP_password.size1); gaa_index++; -#line 55 "certtool.gaa" +#line 57 "certtool.gaa" { gaaval->pass = GAATMP_password.arg1 ;}; return GAA_OK; @@ -980,7 +1012,7 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) GAA_TESTMOREARGS; GAA_FILL(GAATMP_load_ca_certificate.arg1, gaa_getstr, GAATMP_load_ca_certificate.size1); gaa_index++; -#line 52 "certtool.gaa" +#line 54 "certtool.gaa" { gaaval->ca = GAATMP_load_ca_certificate.arg1 ;}; return GAA_OK; @@ -990,7 +1022,7 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) GAA_TESTMOREARGS; GAA_FILL(GAATMP_load_ca_privkey.arg1, gaa_getstr, GAATMP_load_ca_privkey.size1); gaa_index++; -#line 49 "certtool.gaa" +#line 51 "certtool.gaa" { gaaval->ca_privkey = GAATMP_load_ca_privkey.arg1 ;}; return GAA_OK; @@ -1000,7 +1032,7 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) GAA_TESTMOREARGS; GAA_FILL(GAATMP_load_certificate.arg1, gaa_getstr, GAATMP_load_certificate.size1); gaa_index++; -#line 46 "certtool.gaa" +#line 48 "certtool.gaa" { gaaval->cert = GAATMP_load_certificate.arg1 ;}; return GAA_OK; @@ -1010,7 +1042,7 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) GAA_TESTMOREARGS; GAA_FILL(GAATMP_load_request.arg1, gaa_getstr, GAATMP_load_request.size1); gaa_index++; -#line 43 "certtool.gaa" +#line 45 "certtool.gaa" { gaaval->request = GAATMP_load_request.arg1 ;}; return GAA_OK; @@ -1020,85 +1052,85 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) GAA_TESTMOREARGS; GAA_FILL(GAATMP_load_privkey.arg1, gaa_getstr, GAATMP_load_privkey.size1); gaa_index++; -#line 40 "certtool.gaa" +#line 42 "certtool.gaa" { gaaval->privkey = GAATMP_load_privkey.arg1 ;}; return GAA_OK; break; case GAAOPTID_get_dh_params: OK = 0; -#line 37 "certtool.gaa" -{ gaaval->action=16; ;}; +#line 39 "certtool.gaa" +{ gaaval->action=ACTION_GET_DH; ;}; return GAA_OK; break; case GAAOPTID_generate_dh_params: OK = 0; -#line 36 "certtool.gaa" -{ gaaval->action=10; ;}; +#line 38 "certtool.gaa" +{ gaaval->action=ACTION_GENERATE_DH; ;}; return GAA_OK; break; case GAAOPTID_verify_crl: OK = 0; -#line 34 "certtool.gaa" -{ gaaval->action=14; ;}; +#line 36 "certtool.gaa" +{ gaaval->action=ACTION_VERIFY_CRL; ;}; return GAA_OK; break; case GAAOPTID_verify_chain: OK = 0; -#line 32 "certtool.gaa" -{ gaaval->action=5; ;}; +#line 34 "certtool.gaa" +{ gaaval->action=ACTION_VERIFY_CHAIN; ;}; return GAA_OK; break; case GAAOPTID_generate_request: OK = 0; -#line 30 "certtool.gaa" -{ gaaval->action=3; ;}; +#line 32 "certtool.gaa" +{ gaaval->action=ACTION_GENERATE_REQUEST; ;}; return GAA_OK; break; case GAAOPTID_generate_privkey: OK = 0; -#line 28 "certtool.gaa" -{ gaaval->privkey_op=1; gaaval->action=1; ;}; +#line 30 "certtool.gaa" +{ gaaval->privkey_op=1; gaaval->action=ACTION_GENERATE_PRIVKEY; ;}; return GAA_OK; break; case GAAOPTID_update_certificate: OK = 0; -#line 26 "certtool.gaa" -{ gaaval->action=7; ;}; +#line 28 "certtool.gaa" +{ gaaval->action=ACTION_UPDATE_CERTIFICATE; ;}; return GAA_OK; break; case GAAOPTID_generate_crl: OK = 0; -#line 24 "certtool.gaa" -{ gaaval->action=13; ;}; +#line 26 "certtool.gaa" +{ gaaval->action=ACTION_GENERATE_CRL; ;}; return GAA_OK; break; case GAAOPTID_generate_proxy: OK = 0; -#line 22 "certtool.gaa" -{ gaaval->action=17; ;}; +#line 24 "certtool.gaa" +{ gaaval->action=ACTION_GENERATE_PROXY; ;}; return GAA_OK; break; case GAAOPTID_generate_certificate: OK = 0; -#line 20 "certtool.gaa" -{ gaaval->action=4; ;}; +#line 22 "certtool.gaa" +{ gaaval->action=ACTION_GENERATE_CERTIFICATE; ;}; return GAA_OK; break; case GAAOPTID_generate_self_signed: OK = 0; -#line 18 "certtool.gaa" -{ gaaval->action=0; ;}; +#line 20 "certtool.gaa" +{ gaaval->action=ACTION_SELF_SIGNED; ;}; return GAA_OK; break; @@ -1126,7 +1158,7 @@ int gaa(int argc, char **argv, gaainfo *gaaval) if(inited == 0) { -#line 130 "certtool.gaa" +#line 134 "certtool.gaa" { gaaval->bits = 2048; 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->v1_cert = 0; @@ -1279,7 +1311,7 @@ static int gaa_internal_get_next_str(FILE *file, gaa_str_node *tmp_str, int argc len++; a = fgetc( file); - if(a==EOF) return 0; /* a = ' '; */ + if(a==EOF) return 0; //a = ' '; } len += 1; diff --git a/src/certtool-gaa.h b/src/certtool-gaa.h index a95546562d..a8ae82469e 100644 --- a/src/certtool-gaa.h +++ b/src/certtool-gaa.h @@ -8,49 +8,49 @@ typedef struct _gaainfo gaainfo; struct _gaainfo { -#line 123 "certtool.gaa" +#line 127 "certtool.gaa" int debug; -#line 119 "certtool.gaa" +#line 123 "certtool.gaa" char *template; -#line 116 "certtool.gaa" +#line 120 "certtool.gaa" char *infile; -#line 113 "certtool.gaa" +#line 117 "certtool.gaa" char *outfile; -#line 110 "certtool.gaa" +#line 114 "certtool.gaa" int quick_random; -#line 107 "certtool.gaa" +#line 111 "certtool.gaa" int bits; -#line 103 "certtool.gaa" +#line 107 "certtool.gaa" int outcert_format; -#line 99 "certtool.gaa" +#line 103 "certtool.gaa" int incert_format; -#line 96 "certtool.gaa" +#line 100 "certtool.gaa" int export; -#line 93 "certtool.gaa" +#line 97 "certtool.gaa" char *hash; -#line 90 "certtool.gaa" +#line 94 "certtool.gaa" int dsa; -#line 87 "certtool.gaa" +#line 91 "certtool.gaa" int pkcs8; -#line 80 "certtool.gaa" +#line 84 "certtool.gaa" int v1_cert; -#line 77 "certtool.gaa" +#line 81 "certtool.gaa" int fix_key; -#line 54 "certtool.gaa" +#line 56 "certtool.gaa" char *pass; -#line 51 "certtool.gaa" +#line 53 "certtool.gaa" char *ca; -#line 48 "certtool.gaa" +#line 50 "certtool.gaa" char *ca_privkey; -#line 45 "certtool.gaa" +#line 47 "certtool.gaa" char *cert; -#line 42 "certtool.gaa" +#line 44 "certtool.gaa" char *request; -#line 39 "certtool.gaa" +#line 41 "certtool.gaa" char *privkey; -#line 17 "certtool.gaa" +#line 19 "certtool.gaa" int action; -#line 16 "certtool.gaa" +#line 18 "certtool.gaa" int privkey_op; #line 114 "gaa.skel" diff --git a/src/certtool.c b/src/certtool.c index fe57304d86..ba7a87dd29 100644 --- a/src/certtool.c +++ b/src/certtool.c @@ -30,6 +30,7 @@ #include #include #include "certtool-gaa.h" +#include "certtool-common.h" #include #include #include @@ -48,6 +49,7 @@ static void print_crl_info (gnutls_x509_crl_t crl, FILE * out); int generate_prime (int bits, int how); void pkcs7_info (void); +void crq_info (void); void smime_to_pkcs7 (void); void pkcs12_info (void); void generate_pkcs12 (void); @@ -406,8 +408,8 @@ generate_certificate (gnutls_x509_privkey_t * ret_key, if (!proxy) { - get_dns_name_set( crt); - get_ip_addr_set( crt); + get_dns_name_set( TYPE_CRT, crt); + get_ip_addr_set( TYPE_CRT, crt); } result = @@ -418,7 +420,7 @@ generate_certificate (gnutls_x509_privkey_t * ret_key, } else if (!proxy) { - get_email_set( crt); + get_email_set( TYPE_CRT, crt); } if (!ca_status || server) @@ -931,74 +933,77 @@ gaa_parser (int argc, char **argv) switch (info.action) { - case 0: + case ACTION_SELF_SIGNED: generate_self_signed (); break; - case 1: + case ACTION_GENERATE_PRIVKEY: generate_private_key (); break; - case 2: + case ACTION_CERT_INFO: certificate_info (); break; - case 3: + case ACTION_GENERATE_REQUEST: generate_request (); break; - case 4: + case ACTION_GENERATE_CERTIFICATE: generate_signed_certificate (); break; - case 5: + case ACTION_VERIFY_CHAIN: verify_chain (); break; - case 6: + case ACTION_PRIVKEY_INFO: privkey_info (); break; - case 7: + case ACTION_UPDATE_CERTIFICATE: update_signed_certificate (); break; - case 8: + case ACTION_TO_PKCS12: generate_pkcs12 (); break; - case 9: + case ACTION_PKCS12_INFO: pkcs12_info (); break; - case 10: + case ACTION_GENERATE_DH: generate_prime (info.bits, 1); break; - case 16: + case ACTION_GET_DH: generate_prime (info.bits, 0); break; - case 11: + case ACTION_CRL_INFO: crl_info (); break; - case 12: + case ACTION_P7_INFO: pkcs7_info (); break; - case 13: + case ACTION_GENERATE_CRL: generate_signed_crl (); break; - case 14: + case ACTION_VERIFY_CRL: verify_crl (); break; - case 15: + case ACTION_SMIME_TO_P7: smime_to_pkcs7 (); break; - case 17: + case ACTION_GENERATE_PROXY: generate_proxy_certificate (); break; - case 18: + case ACTION_GENERATE_PKCS8: generate_pkcs8 (); break; #ifdef ENABLE_OPENPGP - case 19: + case ACTION_PGP_INFO: pgp_certificate_info (); break; - case 20: + case ACTION_PGP_PRIVKEY_INFO: pgp_privkey_info (); break; - case 21: + case ACTION_RING_INFO: pgp_ring_info (); break; #endif + case ACTION_REQUEST: + crq_info(); + break; default: gaa_help (); exit (0); @@ -1390,6 +1395,59 @@ crl_info (void) gnutls_x509_crl_deinit (crl); } +static void +print_crq_info (gnutls_x509_crq_t crq, FILE * out) +{ + gnutls_datum_t info; + int ret; + size_t size; + + ret = gnutls_x509_crq_print (crq, GNUTLS_CRT_PRINT_FULL, &info); + if (ret < 0) + error (EXIT_FAILURE, 0, "crq_print: %s", gnutls_strerror (ret)); + + fprintf (out, "%s\n", info.data); + + gnutls_free (info.data); + + size = sizeof (buffer); + ret = gnutls_x509_crq_export (crq, GNUTLS_X509_FMT_PEM, buffer, &size); + if (ret < 0) + error (EXIT_FAILURE, 0, "crq_export: %s", gnutls_strerror (ret)); + + fwrite (buffer, 1, size, outfile); +} + +void +crq_info (void) +{ + gnutls_x509_crq_t crq; + int ret; + size_t size; + gnutls_datum_t pem; + + ret = gnutls_x509_crq_init (&crq); + if (ret < 0) + error (EXIT_FAILURE, 0, "crq_init: %s", gnutls_strerror (ret)); + + pem.data = fread_file (infile, &size); + pem.size = size; + + if (!pem.data) + error (EXIT_FAILURE, errno, "%s", info.infile ? info.infile : + "standard input"); + + ret = gnutls_x509_crq_import (crq, &pem, info.incert_format); + + free (pem.data); + if (ret < 0) + error (EXIT_FAILURE, 0, "Import error: %s", gnutls_strerror (ret)); + + print_crq_info (crq, outfile); + + gnutls_x509_crq_deinit (crq); +} + void privkey_info (void) { @@ -1766,9 +1824,10 @@ generate_request (void) { gnutls_x509_crq_t crq; gnutls_x509_privkey_t key; - int ret; + int ret, ca_status, path_len; const char *pass; size_t size; + unsigned int usage; fprintf (stderr, "Generating a PKCS #10 certificate request...\n"); @@ -1797,15 +1856,57 @@ generate_request (void) get_uid_crq_set (crq); get_oid_crq_set (crq); + get_dns_name_set( TYPE_CRQ, crq); + get_ip_addr_set( TYPE_CRQ, crq); + get_email_set( TYPE_CRQ, crq); + pass = get_challenge_pass (); - if (pass != NULL) + if (pass != NULL && pass[0] != 0) { ret = gnutls_x509_crq_set_challenge_password (crq, pass); if (ret < 0) error (EXIT_FAILURE, 0, "set_pass: %s", gnutls_strerror (ret)); } + ca_status = get_ca_status (); + if (ca_status) + path_len = get_path_len (); + else + path_len = -1; + + ret = + gnutls_x509_crq_set_basic_constraints (crq, ca_status, path_len); + if (ret < 0) + error (EXIT_FAILURE, 0, "set_basic_constraints: %s", gnutls_strerror (ret)); + + + ret = get_sign_status (1); + if (ret) + usage |= GNUTLS_KEY_DIGITAL_SIGNATURE; + + ret = get_encrypt_status (1); + if (ret) + usage |= GNUTLS_KEY_KEY_ENCIPHERMENT; + else + usage |= GNUTLS_KEY_DIGITAL_SIGNATURE; + + if (ca_status) + { + ret = get_cert_sign_status (); + if (ret) + usage |= GNUTLS_KEY_KEY_CERT_SIGN; + + ret = get_crl_sign_status (); + if (ret) + usage |= GNUTLS_KEY_CRL_SIGN; + } + + ret = gnutls_x509_crq_set_key_usage (crq, usage); + if (ret < 0) + error (EXIT_FAILURE, 0, "key_usage: %s", + gnutls_strerror (ret)); + ret = gnutls_x509_crq_set_key (crq, key); if (ret < 0) error (EXIT_FAILURE, 0, "set_key: %s", gnutls_strerror (ret)); diff --git a/src/certtool.gaa b/src/certtool.gaa index 623678405b..87def6d75e 100644 --- a/src/certtool.gaa +++ b/src/certtool.gaa @@ -9,32 +9,34 @@ void certtool_version(void); +#include "certtool-common.h" + #} helpnode "Certtool help\nUsage: certtool [options]" #int privkey_op; #int action; -option (s, generate-self-signed) { $action=0; } "Generate a self-signed certificate." +option (s, generate-self-signed) { $action=ACTION_SELF_SIGNED; } "Generate a self-signed certificate." -option (c, generate-certificate) { $action=4; } "Generate a signed certificate." +option (c, generate-certificate) { $action=ACTION_GENERATE_CERTIFICATE; } "Generate a signed certificate." -option (generate-proxy) { $action=17; } "Generate a proxy certificate." +option (generate-proxy) { $action=ACTION_GENERATE_PROXY; } "Generate a proxy certificate." -option (generate-crl) { $action=13; } "Generate a CRL." +option (generate-crl) { $action=ACTION_GENERATE_CRL; } "Generate a CRL." -option (u, update-certificate) { $action=7; } "Update a signed certificate." +option (u, update-certificate) { $action=ACTION_UPDATE_CERTIFICATE; } "Update a signed certificate." -option (p, generate-privkey) { $privkey_op=1; $action=1; } "Generate a private key." +option (p, generate-privkey) { $privkey_op=1; $action=ACTION_GENERATE_PRIVKEY; } "Generate a private key." -option (q, generate-request) { $action=3; } "Generate a PKCS #10 certificate request." +option (q, generate-request) { $action=ACTION_GENERATE_REQUEST; } "Generate a PKCS #10 certificate request." -option (e, verify-chain) { $action=5; } "Verify a PEM encoded certificate chain. The last certificate in the chain must be a self signed one." +option (e, verify-chain) { $action=ACTION_VERIFY_CHAIN; } "Verify a PEM encoded certificate chain. The last certificate in the chain must be a self signed one." -option (verify-crl) { $action=14; } "Verify a CRL." +option (verify-crl) { $action=ACTION_VERIFY_CRL; } "Verify a CRL." -option (generate-dh-params) { $action=10; } "Generate PKCS #3 encoded Diffie Hellman parameters." -option (get-dh-params) { $action=16; } "Get the included PKCS #3 encoded Diffie Hellman parameters." +option (generate-dh-params) { $action=ACTION_GENERATE_DH; } "Generate PKCS #3 encoded Diffie Hellman parameters." +option (get-dh-params) { $action=ACTION_GET_DH; } "Get the included PKCS #3 encoded Diffie Hellman parameters." #char *privkey; option (load-privkey) STR "FILE" { $privkey = $1 } "Private key file to use." @@ -54,25 +56,27 @@ option (load-ca-certificate) STR "FILE" { $ca = $1 } "Certificate authority's ce #char *pass; option (password) STR "PASSWORD" { $pass = $1 } "Password to use." -option (i, certificate-info) { $action = 2; } "Print information on a certificate." +option (i, certificate-info) { $action = ACTION_CERT_INFO; } "Print information on a certificate." + +option (pgp-certificate-info) { $action = ACTION_PGP_INFO; } "Print information on a OpenPGP certificate." -option (pgp-certificate-info) { $action = 19; } "Print information on a OpenPGP certificate." +option (pgp-ring-info) { $action = ACTION_RING_INFO; } "Print information on a keyring structure." -option (pgp-ring-info) { $action = 21; } "Print information on a keyring structure." +option (l, crl-info) { $action = ACTION_CRL_INFO; } "Print information on a CRL." -option (l, crl-info) { $action = 11; } "Print information on a CRL." +option (crq-info) { $action = ACTION_REQUEST; } "Print information on a Certificate Request." -option (p12-info) { $action = 9; } "Print information on a PKCS #12 structure." +option (p12-info) { $action = ACTION_PKCS12_INFO; } "Print information on a PKCS #12 structure." -option (p7-info) { $action = 12; } "Print information on a PKCS #7 structure." +option (p7-info) { $action = ACTION_P7_INFO; } "Print information on a PKCS #7 structure." -option (smime-to-p7) { $action = 15; } "Convert S/MIME to PKCS #7 structure." +option (smime-to-p7) { $action = ACTION_SMIME_TO_P7; } "Convert S/MIME to PKCS #7 structure." /* on private key operations set $privkey_op to != 0 */ -option (k, key-info) { $privkey_op=1; $action = 6; } "Print information on a private key." +option (k, key-info) { $privkey_op=1; $action = ACTION_PRIVKEY_INFO; } "Print information on a private key." -option (pgp-key-info) { $privkey_op=1; $action = 20; } "Print information on a OpenPGP private key." +option (pgp-key-info) { $privkey_op=1; $action = ACTION_PGP_PRIVKEY_INFO; } "Print information on a OpenPGP private key." #int fix_key; option (fix-key) { $privkey_op=1; $fix_key = 1; } "Regenerate the parameters in a private key." @@ -80,9 +84,9 @@ option (fix-key) { $privkey_op=1; $fix_key = 1; } "Regenerate the parameters in #int v1_cert; option (v1) { $v1_cert = 1; } "Generate an X.509 version 1 certificate (no extensions)." -option (to-p12) { $action = 8; } "Generate a PKCS #12 structure." +option (to-p12) { $action = ACTION_TO_PKCS12; } "Generate a PKCS #12 structure." -option (to-p8) { $action = 18; } "Generate a PKCS #8 key structure." +option (to-p8) { $action = ACTION_GENERATE_PKCS8; } "Generate a PKCS #8 key structure." #int pkcs8; option (8, pkcs8) { $pkcs8=1 } "Use PKCS #8 format for private keys."