summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Josefsson <simon@josefsson.org>2007-04-06 10:54:17 +0000
committerSimon Josefsson <simon@josefsson.org>2007-04-06 10:54:17 +0000
commit9c5dff71d17ae3dc85d8fc9e9e1a7b165e9a5db3 (patch)
tree5392895395e9bd1212126851b431ad361d5738b6
parent47bfe61d3f583c238ce4b3211afc032f5203591b (diff)
downloadgnutls-9c5dff71d17ae3dc85d8fc9e9e1a7b165e9a5db3.tar.gz
(gnutls_x509_crt_get_key_id): Don't fail on non-RSA/DSA public keys.
-rw-r--r--lib/x509/x509.c147
1 files changed, 98 insertions, 49 deletions
diff --git a/lib/x509/x509.c b/lib/x509/x509.c
index 9b8f244cb4..956dbfb8e3 100644
--- a/lib/x509/x509.c
+++ b/lib/x509/x509.c
@@ -1954,61 +1954,18 @@ gnutls_x509_crt_export (gnutls_x509_crt_t cert,
}
-/**
- * gnutls_x509_crt_get_key_id - Return unique ID of public key's parameters
- * @crt: Holds the certificate
- * @flags: should be 0 for now
- * @output_data: will contain the key ID
- * @output_data_size: holds the size of output_data (and will be
- * replaced by the actual size of parameters)
- *
- * This function will return a unique ID the depends on the public key
- * parameters. This ID can be used in checking whether a certificate
- * corresponds to the given private key.
- *
- * If the buffer provided is not long enough to hold the output, then
- * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
- * be returned. The output will normally be a SHA-1 hash output,
- * which is 20 bytes.
- *
- * Return value: In case of failure a negative value will be
- * returned, and 0 on success.
- *
- **/
-int
-gnutls_x509_crt_get_key_id (gnutls_x509_crt_t crt, unsigned int flags,
- unsigned char *output_data,
- size_t * output_data_size)
+static int
+rsadsa_get_key_id (gnutls_x509_crt_t crt, int pk,
+ unsigned char *output_data,
+ size_t * output_data_size)
{
mpi_t params[MAX_PUBLIC_PARAMS_SIZE];
int params_size = MAX_PUBLIC_PARAMS_SIZE;
- int i, pk, result = 0;
+ int i, result = 0;
gnutls_datum_t der = { NULL, 0 };
GNUTLS_HASH_HANDLE hd;
- if (crt == NULL)
- {
- gnutls_assert ();
- return GNUTLS_E_INVALID_REQUEST;
- }
-
- if (*output_data_size < 20)
- {
- gnutls_assert ();
- *output_data_size = 20;
- return GNUTLS_E_SHORT_MEMORY_BUFFER;
- }
-
- pk = gnutls_x509_crt_get_pk_algorithm (crt, NULL);
-
- if (pk < 0)
- {
- gnutls_assert ();
- return pk;
- }
-
result = _gnutls_x509_crt_get_mpis (crt, params, &params_size);
-
if (result < 0)
{
gnutls_assert ();
@@ -2051,7 +2008,7 @@ gnutls_x509_crt_get_key_id (gnutls_x509_crt_t crt, unsigned int flags,
result = 0;
-cleanup:
+ cleanup:
_gnutls_free_datum (&der);
@@ -2064,6 +2021,98 @@ cleanup:
return result;
}
+/**
+ * gnutls_x509_crt_get_key_id - Return unique ID of public key's parameters
+ * @crt: Holds the certificate
+ * @flags: should be 0 for now
+ * @output_data: will contain the key ID
+ * @output_data_size: holds the size of output_data (and will be
+ * replaced by the actual size of parameters)
+ *
+ * This function will return a unique ID the depends on the public
+ * key parameters. This ID can be used in checking whether a
+ * certificate corresponds to the given private key.
+ *
+ * If the buffer provided is not long enough to hold the output, then
+ * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
+ * be returned. The output will normally be a SHA-1 hash output,
+ * which is 20 bytes.
+ *
+ * Return value: In case of failure a negative value will be
+ * returned, and 0 on success.
+ *
+ **/
+int
+gnutls_x509_crt_get_key_id (gnutls_x509_crt_t crt, unsigned int flags,
+ unsigned char *output_data,
+ size_t * output_data_size)
+{
+ int pk, result = 0;
+ gnutls_datum_t pubkey;
+
+ if (crt == NULL)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
+ if (*output_data_size < 20)
+ {
+ gnutls_assert ();
+ *output_data_size = 20;
+ return GNUTLS_E_SHORT_MEMORY_BUFFER;
+ }
+
+ pk = gnutls_x509_crt_get_pk_algorithm (crt, NULL);
+ if (pk < 0)
+ {
+ gnutls_assert ();
+ return pk;
+ }
+
+ if (pk == GNUTLS_PK_RSA || pk == GNUTLS_PK_DSA)
+ {
+ /* This is for compatibility with what GnuTLS has printed for
+ RSA/DSA before the code below was added. The code below is
+ applicable to all types, and it would probably be a better
+ idea to use it for RSA/DSA too, but doing so would break
+ backwards compatibility. */
+ return rsadsa_get_key_id (crt, pk, output_data, output_data_size);
+ }
+
+ pubkey.size = 0;
+ result = asn1_der_coding (crt->cert, "tbsCertificate.subjectPublicKeyInfo",
+ NULL, &pubkey.size, NULL);
+ if (result != ASN1_MEM_ERROR)
+ {
+ gnutls_assert ();
+ return _gnutls_asn2err (result);
+ }
+
+ pubkey.data = gnutls_alloca (pubkey.size);
+ if (pubkey.data == NULL)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ result = asn1_der_coding (crt->cert, "tbsCertificate.subjectPublicKeyInfo",
+ pubkey.data, &pubkey.size, NULL);
+ if (result != ASN1_SUCCESS)
+ {
+ gnutls_assert ();
+ gnutls_afree (pubkey.data);
+ return _gnutls_asn2err (result);
+ }
+
+ result = gnutls_fingerprint (GNUTLS_DIG_SHA1, &pubkey,
+ output_data, output_data_size);
+
+ gnutls_afree (pubkey.data);
+
+ return result;
+}
+
#ifdef ENABLE_PKI