summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2012-10-11 20:47:46 +0200
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2012-10-11 22:05:44 +0200
commit00ff88629c1c8a391a0515e87e5cd98259b77c6c (patch)
treefc30a7c610d0b6e4831cb29f3da54b15fb4ea26c
parent3a8d9b33d8bf9d5fb53f051e92db5d4d88fc1f90 (diff)
downloadgnutls-00ff88629c1c8a391a0515e87e5cd98259b77c6c.tar.gz
Several OpenPGP updates.
Exported gnutls_certificate_get_peers_subkey_id(). Removed compatibility code with RFC5081. The gnutls_openpgp_*_get_subkey_*() functions return the master key parameters if provided with GNUTLS_OPENPGP_MASTER_KEYID_IDX.
-rw-r--r--NEWS4
-rw-r--r--lib/auth/cert.c115
-rw-r--r--lib/auth/cert.h1
-rw-r--r--lib/gnutls_pcert.c3
-rw-r--r--lib/gnutls_pubkey.c9
-rw-r--r--lib/gnutls_ui.c27
-rw-r--r--lib/includes/gnutls/gnutls.h.in3
-rw-r--r--lib/includes/gnutls/openpgp.h3
-rw-r--r--lib/libgnutls.map1
-rw-r--r--lib/openpgp/pgp.c56
-rw-r--r--lib/openpgp/privkey.c73
11 files changed, 182 insertions, 113 deletions
diff --git a/NEWS b/NEWS
index 21c7777c6b..b2fc91d3be 100644
--- a/NEWS
+++ b/NEWS
@@ -27,6 +27,9 @@ response corresponds to the given certificate.
OCSP certificate status request extensions by default. The flag
GNUTLS_NO_EXTENSIONS can be used to prevent that.
+** libgnutls: Compatibility code with RFC5081 was removed. The OpenPGP
+code now is RFC6091 compliant only.
+
** libgnutls-dane: Added. It is a library to provide DANE with DNSSEC
certificate verification.
@@ -35,6 +38,7 @@ certificate verification.
** certtool: The --dane-tlsa-rr option generates DANE TLSA Resource Records (RR).
** API and ABI modifications:
+gnutls_certificate_get_peers_subkey_id: Added
gnutls_certificate_set_ocsp_status_request_function: Added
gnutls_certificate_set_ocsp_status_request_file: Added
gnutls_ocsp_status_request_enable_client: Added
diff --git a/lib/auth/cert.c b/lib/auth/cert.c
index 34bc6d2dd4..95bd6d06e5 100644
--- a/lib/auth/cert.c
+++ b/lib/auth/cert.c
@@ -73,7 +73,7 @@ typedef enum CertificateSigType
* exported certificate struct (cert_auth_info_t)
*/
static int
-_gnutls_copy_certificate_auth_info (cert_auth_info_t info, gnutls_pcert_st * certs, size_t ncerts, int subkey_used, /* openpgp only */
+_gnutls_copy_certificate_auth_info (cert_auth_info_t info, gnutls_pcert_st * certs, size_t ncerts, /* openpgp only */
void *keyid)
{
/* Copy peer's information to auth_info_t
@@ -123,7 +123,6 @@ _gnutls_copy_certificate_auth_info (cert_auth_info_t info, gnutls_pcert_st * cer
#ifdef ENABLE_OPENPGP
if (certs[0].type == GNUTLS_CRT_OPENPGP)
{
- info->use_subkey = subkey_used;
if (keyid)
memcpy (info->subkey_id, keyid, GNUTLS_OPENPGP_KEYID_SIZE);
}
@@ -846,7 +845,7 @@ _gnutls_gen_x509_crt (gnutls_session_t session, gnutls_buffer_st * data)
}
enum PGPKeyDescriptorType
-{ PGP_KEY_FINGERPRINT, PGP_KEY, PGP_KEY_SUBKEY, PGP_KEY_FINGERPRINT_SUBKEY };
+{ PGP_EMPTY_KEY=1, PGP_KEY_SUBKEY, PGP_KEY_FINGERPRINT_SUBKEY };
#ifdef ENABLE_OPENPGP
static int
@@ -860,7 +859,6 @@ _gnutls_gen_openpgp_certificate (gnutls_session_t session,
uint8_t type;
uint8_t fpr[20];
size_t fpr_size;
- unsigned int use_subkey = 0;
/* find the appropriate certificate */
if ((ret =
@@ -880,12 +878,11 @@ _gnutls_gen_openpgp_certificate (gnutls_session_t session,
fpr_size = sizeof (fpr);
ret =
gnutls_pubkey_get_openpgp_key_id (apr_cert_list[0].pubkey, 0, fpr,
- &fpr_size, &use_subkey);
+ &fpr_size, NULL);
if (ret < 0)
return gnutls_assert_val (ret);
- if (use_subkey != 0)
- ret += 1 + fpr_size; /* for the keyid */
+ ret += 1 + fpr_size; /* for the keyid */
ret += apr_cert_list[0].cert.size;
}
@@ -897,25 +894,15 @@ _gnutls_gen_openpgp_certificate (gnutls_session_t session,
if (apr_cert_list_length > 0)
{
- if (use_subkey != 0)
- {
- type = PGP_KEY_SUBKEY;
+ type = PGP_KEY_SUBKEY;
- ret = _gnutls_buffer_append_data (data, &type, 1);
- if (ret < 0)
- return gnutls_assert_val (ret);
+ ret = _gnutls_buffer_append_data (data, &type, 1);
+ if (ret < 0)
+ return gnutls_assert_val (ret);
- ret = _gnutls_buffer_append_data_prefix (data, 8, fpr, fpr_size);
- if (ret < 0)
- return gnutls_assert_val (ret);
- }
- else
- {
- type = PGP_KEY;
- ret = _gnutls_buffer_append_data (data, &type, 1);
- if (ret < 0)
- return gnutls_assert_val (ret);
- }
+ ret = _gnutls_buffer_append_data_prefix (data, 8, fpr, fpr_size);
+ if (ret < 0)
+ return gnutls_assert_val (ret);
ret =
_gnutls_buffer_append_data_prefix (data, 24,
@@ -926,7 +913,7 @@ _gnutls_gen_openpgp_certificate (gnutls_session_t session,
}
else /* empty - no certificate */
{
- type = PGP_KEY;
+ type = PGP_EMPTY_KEY;
ret = _gnutls_buffer_append_data (data, &type, 1);
if (ret < 0)
@@ -950,7 +937,6 @@ _gnutls_gen_openpgp_certificate_fpr (gnutls_session_t session,
gnutls_pcert_st *apr_cert_list;
gnutls_privkey_t apr_pkey;
int apr_cert_list_length;
- unsigned int use_subkey = 0;
/* find the appropriate certificate */
if ((ret =
@@ -964,14 +950,12 @@ _gnutls_gen_openpgp_certificate_fpr (gnutls_session_t session,
fpr_size = sizeof (fpr);
ret =
gnutls_pubkey_get_openpgp_key_id (apr_cert_list[0].pubkey, 0, fpr,
- &fpr_size, &use_subkey);
+ &fpr_size, NULL);
if (ret < 0)
return gnutls_assert_val (ret);
packet_size = 3 + 1;
-
- if (use_subkey)
- packet_size += 1 + fpr_size; /* for the keyid */
+ packet_size += 1 + fpr_size; /* for the keyid */
/* Only v4 fingerprints are sent
*/
@@ -984,33 +968,10 @@ _gnutls_gen_openpgp_certificate_fpr (gnutls_session_t session,
if (ret < 0)
return gnutls_assert_val (ret);
- if (use_subkey)
- {
- type = PGP_KEY_FINGERPRINT_SUBKEY;
- ret = _gnutls_buffer_append_data (data, &type, 1);
- if (ret < 0)
- return gnutls_assert_val (ret);
-
- ret = _gnutls_buffer_append_data_prefix (data, 8, fpr, fpr_size);
- if (ret < 0)
- return gnutls_assert_val (ret);
- }
- else
- {
- type = PGP_KEY_FINGERPRINT; /* key fingerprint */
- ret = _gnutls_buffer_append_data (data, &type, 1);
- if (ret < 0)
- return gnutls_assert_val (ret);
- }
-
- fpr_size = sizeof (fpr);
- if ((ret =
- _gnutls_openpgp_fingerprint (&apr_cert_list[0].cert, fpr,
- &fpr_size)) < 0)
- {
- gnutls_assert ();
- return ret;
- }
+ type = PGP_KEY_FINGERPRINT_SUBKEY;
+ ret = _gnutls_buffer_append_data (data, &type, 1);
+ if (ret < 0)
+ return gnutls_assert_val (ret);
ret = _gnutls_buffer_append_data_prefix (data, 8, fpr, fpr_size);
if (ret < 0)
@@ -1182,7 +1143,7 @@ _gnutls_proc_x509_server_crt (gnutls_session_t session,
if ((ret =
_gnutls_copy_certificate_auth_info (info,
peer_certificate_list,
- peer_certificate_list_size, 0,
+ peer_certificate_list_size,
NULL)) < 0)
{
gnutls_assert ();
@@ -1220,7 +1181,6 @@ _gnutls_proc_openpgp_server_crt (gnutls_session_t session,
gnutls_pcert_st *peer_certificate_list = NULL;
gnutls_datum_t tmp, akey = { NULL, 0 };
uint8_t subkey_id[GNUTLS_OPENPGP_KEYID_SIZE];
- unsigned int subkey_id_set = 0;
cred = (gnutls_certificate_credentials_t)
_gnutls_get_cred (session, GNUTLS_CRD_CERTIFICATE, NULL);
@@ -1278,16 +1238,10 @@ _gnutls_proc_openpgp_server_crt (gnutls_session_t session,
DECR_LEN (dsize, GNUTLS_OPENPGP_KEYID_SIZE);
memcpy (subkey_id, p, GNUTLS_OPENPGP_KEYID_SIZE);
p += GNUTLS_OPENPGP_KEYID_SIZE;
-
- subkey_id_set = 1;
-
}
- /* read the actual key or fingerprint */
- if (key_type == PGP_KEY_FINGERPRINT ||
- key_type == PGP_KEY_FINGERPRINT_SUBKEY)
- { /* the fingerprint */
-
+ if (key_type == PGP_KEY_FINGERPRINT_SUBKEY)
+ {
DECR_LEN (dsize, 1);
len = (uint8_t) * p;
p++;
@@ -1311,7 +1265,7 @@ _gnutls_proc_openpgp_server_crt (gnutls_session_t session,
}
tmp = akey;
}
- else if (key_type == PGP_KEY || key_type == PGP_KEY_SUBKEY)
+ else if (key_type == PGP_KEY_SUBKEY)
{ /* the whole key */
/* Read the actual certificate */
@@ -1323,7 +1277,7 @@ _gnutls_proc_openpgp_server_crt (gnutls_session_t session,
{
gnutls_assert ();
/* no certificate was sent */
- return GNUTLS_E_NO_CERTIFICATE_FOUND;
+ return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
}
DECR_LEN (dsize, len);
@@ -1332,6 +1286,19 @@ _gnutls_proc_openpgp_server_crt (gnutls_session_t session,
tmp.data = p;
}
+ else if (key_type == PGP_EMPTY_KEY)
+ { /* the whole key */
+
+ /* Read the actual certificate */
+ DECR_LEN (dsize, 3);
+ len = _gnutls_read_uint24 (p);
+ p += 3;
+
+ if (len != 0) /* PGP_EMPTY_KEY */
+ return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
+ else
+ return GNUTLS_E_NO_CERTIFICATE_FOUND;
+ }
else
{
gnutls_assert ();
@@ -1341,8 +1308,7 @@ _gnutls_proc_openpgp_server_crt (gnutls_session_t session,
/* ok we now have the peer's key in tmp datum
*/
peer_certificate_list =
- gnutls_calloc (1,
- sizeof (gnutls_pcert_st));
+ gnutls_calloc (1, sizeof (gnutls_pcert_st));
if (peer_certificate_list == NULL)
{
gnutls_assert ();
@@ -1354,7 +1320,7 @@ _gnutls_proc_openpgp_server_crt (gnutls_session_t session,
gnutls_pcert_import_openpgp_raw (&peer_certificate_list[0],
&tmp,
GNUTLS_OPENPGP_FMT_RAW,
- (subkey_id_set != 0) ? subkey_id : NULL,
+ subkey_id,
0);
if (ret < 0)
{
@@ -1365,10 +1331,7 @@ _gnutls_proc_openpgp_server_crt (gnutls_session_t session,
ret =
_gnutls_copy_certificate_auth_info (info,
peer_certificate_list,
- 1,
- subkey_id_set,
- (subkey_id_set !=
- 0) ? subkey_id : NULL);
+ 1, subkey_id);
if (ret < 0)
{
gnutls_assert ();
diff --git a/lib/auth/cert.h b/lib/auth/cert.h
index b253e79349..93f7e52e6b 100644
--- a/lib/auth/cert.h
+++ b/lib/auth/cert.h
@@ -118,7 +118,6 @@ typedef struct cert_auth_info_st
gnutls_certificate_type_t cert_type;
#ifdef ENABLE_OPENPGP
- int use_subkey;
uint8_t subkey_id[GNUTLS_OPENPGP_KEYID_SIZE];
#endif
} *cert_auth_info_t;
diff --git a/lib/gnutls_pcert.c b/lib/gnutls_pcert.c
index 1211e2d6fb..3a6b6fee5c 100644
--- a/lib/gnutls_pcert.c
+++ b/lib/gnutls_pcert.c
@@ -396,8 +396,7 @@ _gnutls_get_auth_info_pcert (gnutls_pcert_st* pcert,
return gnutls_pcert_import_openpgp_raw(pcert,
&info->raw_certificate_list[0],
GNUTLS_OPENPGP_FMT_RAW,
- info->use_subkey ? info->
- subkey_id : NULL, GNUTLS_PCERT_NO_CERT);
+ info->subkey_id, GNUTLS_PCERT_NO_CERT);
#endif
default:
gnutls_assert ();
diff --git a/lib/gnutls_pubkey.c b/lib/gnutls_pubkey.c
index c492445e94..253b72249e 100644
--- a/lib/gnutls_pubkey.c
+++ b/lib/gnutls_pubkey.c
@@ -420,14 +420,13 @@ gnutls_pubkey_import_openpgp (gnutls_pubkey_t key,
* replaced by the actual size of parameters)
* @subkey: Will be non zero if the key ID corresponds to a subkey
*
- * 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 public key.
+ * This function returned the OpenPGP key ID of the corresponding key.
+ * The key is a unique ID the depends on the public
+ * key parameters.
*
* 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.
+ * be returned. The output is %GNUTLS_OPENPGP_KEYID_SIZE bytes long.
*
* Returns: In case of failure a negative error code will be
* returned, and 0 on success.
diff --git a/lib/gnutls_ui.c b/lib/gnutls_ui.c
index 654810abbc..1cd53f273c 100644
--- a/lib/gnutls_ui.c
+++ b/lib/gnutls_ui.c
@@ -552,6 +552,33 @@ gnutls_certificate_get_peers (gnutls_session_t
return info->raw_certificate_list;
}
+/**
+ * gnutls_certificate_get_peers_subkey_id:
+ * @session: is a gnutls session
+ * @id: will contain the ID
+ *
+ * Get the peer's subkey ID when OpenPGP certificates are
+ * used. The returned @id should be treated as constant.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
+ * an error code is returned.
+ **/
+int gnutls_certificate_get_peers_subkey_id(gnutls_session_t session,
+ gnutls_datum_t *id)
+{
+ cert_auth_info_t info;
+
+ CHECK_AUTH (GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST);
+
+ info = _gnutls_get_auth_info (session);
+ if (info == NULL)
+ return GNUTLS_E_INVALID_REQUEST;
+
+ id->data = info->subkey_id;
+ id->size = GNUTLS_OPENPGP_KEYID_SIZE;
+
+ return 0;
+}
/**
* gnutls_certificate_client_get_request_status:
diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in
index ec553a03f3..55928ce268 100644
--- a/lib/includes/gnutls/gnutls.h.in
+++ b/lib/includes/gnutls/gnutls.h.in
@@ -1684,6 +1684,9 @@ gnutls_ecc_curve_t gnutls_ecc_curve_get(gnutls_session_t session);
const gnutls_datum_t *gnutls_certificate_get_ours (gnutls_session_t
session);
+ int gnutls_certificate_get_peers_subkey_id(gnutls_session_t session,
+ gnutls_datum_t *id);
+
time_t gnutls_certificate_activation_time_peers (gnutls_session_t session);
time_t gnutls_certificate_expiration_time_peers (gnutls_session_t session);
diff --git a/lib/includes/gnutls/openpgp.h b/lib/includes/gnutls/openpgp.h
index bed810168b..ae612f5fa5 100644
--- a/lib/includes/gnutls/openpgp.h
+++ b/lib/includes/gnutls/openpgp.h
@@ -28,6 +28,7 @@
#define GNUTLS_OPENPGP_H
#include <gnutls/gnutls.h>
+#include <limits.h>
#ifdef __cplusplus
extern "C"
@@ -79,6 +80,8 @@ extern "C"
/* The key_usage flags are defined in gnutls.h. They are
* the GNUTLS_KEY_* definitions.
*/
+#define GNUTLS_OPENPGP_MASTER_KEYID_IDX INT_MAX
+
int gnutls_openpgp_crt_get_key_usage (gnutls_openpgp_crt_t key,
unsigned int *key_usage);
int gnutls_openpgp_crt_get_fingerprint (gnutls_openpgp_crt_t key, void *fpr,
diff --git a/lib/libgnutls.map b/lib/libgnutls.map
index c795ab1843..438120e044 100644
--- a/lib/libgnutls.map
+++ b/lib/libgnutls.map
@@ -856,6 +856,7 @@ GNUTLS_3_1_0 {
gnutls_pkcs12_export2;
gnutls_pubkey_import_openpgp_raw;
gnutls_pubkey_import_x509_raw;
+ gnutls_certificate_get_peers_subkey_id;
} GNUTLS_3_0_0;
GNUTLS_PRIVATE {
diff --git a/lib/openpgp/pgp.c b/lib/openpgp/pgp.c
index 78ef7882b8..97f9491132 100644
--- a/lib/openpgp/pgp.c
+++ b/lib/openpgp/pgp.c
@@ -427,20 +427,22 @@ gnutls_openpgp_crt_get_pk_algorithm (gnutls_openpgp_crt_t key,
int idx;
idx = gnutls_openpgp_crt_get_subkey_idx (key, keyid);
- algo =
- gnutls_openpgp_crt_get_subkey_pk_algorithm (key, idx, NULL);
- }
- else
- {
- pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_PUBLIC_KEY);
- if (pkt)
+ if (idx != GNUTLS_OPENPGP_MASTER_KEYID_IDX)
{
- if (bits)
- *bits = cdk_pk_get_nbits (pkt->pkt.public_key);
- algo = _gnutls_openpgp_get_algo (pkt->pkt.public_key->pubkey_algo);
+ algo =
+ gnutls_openpgp_crt_get_subkey_pk_algorithm (key, idx, bits);
+ return algo;
}
}
+ pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_PUBLIC_KEY);
+ if (pkt)
+ {
+ if (bits)
+ *bits = cdk_pk_get_nbits (pkt->pkt.public_key);
+ algo = _gnutls_openpgp_get_algo (pkt->pkt.public_key->pubkey_algo);
+ }
+
return algo;
}
@@ -856,6 +858,9 @@ gnutls_openpgp_crt_get_subkey_revoked_status (gnutls_openpgp_crt_t key,
return GNUTLS_E_INVALID_REQUEST;
}
+ if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX)
+ return gnutls_openpgp_crt_get_revoked_status(key);
+
pkt = _get_public_subkey (key, idx);
if (!pkt)
return GNUTLS_E_OPENPGP_GETKEY_FAILED;
@@ -897,6 +902,9 @@ gnutls_openpgp_crt_get_subkey_pk_algorithm (gnutls_openpgp_crt_t key,
return GNUTLS_PK_UNKNOWN;
}
+ if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX)
+ return gnutls_openpgp_crt_get_pk_algorithm(key, bits);
+
pkt = _get_public_subkey (key, idx);
algo = 0;
@@ -931,6 +939,9 @@ gnutls_openpgp_crt_get_subkey_creation_time (gnutls_openpgp_crt_t key,
if (!key)
return (time_t) - 1;
+ if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX)
+ return gnutls_openpgp_crt_get_creation_time(key);
+
pkt = _get_public_subkey (key, idx);
if (pkt)
timestamp = pkt->pkt.public_key->timestamp;
@@ -963,6 +974,9 @@ gnutls_openpgp_crt_get_subkey_expiration_time (gnutls_openpgp_crt_t key,
if (!key)
return (time_t) - 1;
+ if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX)
+ return gnutls_openpgp_crt_get_expiration_time(key);
+
pkt = _get_public_subkey (key, idx);
if (pkt)
expiredate = pkt->pkt.public_key->expiredate;
@@ -995,6 +1009,9 @@ gnutls_openpgp_crt_get_subkey_id (gnutls_openpgp_crt_t key,
gnutls_assert ();
return GNUTLS_E_INVALID_REQUEST;
}
+
+ if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX)
+ return gnutls_openpgp_crt_get_key_id(key, keyid);
pkt = _get_public_subkey (key, idx);
if (!pkt)
@@ -1034,6 +1051,9 @@ gnutls_openpgp_crt_get_subkey_fingerprint (gnutls_openpgp_crt_t key,
gnutls_assert ();
return GNUTLS_E_INVALID_REQUEST;
}
+
+ if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX)
+ return gnutls_openpgp_crt_get_fingerprint(key, fpr, fprlen);
*fprlen = 0;
@@ -1069,6 +1089,7 @@ gnutls_openpgp_crt_get_subkey_idx (gnutls_openpgp_crt_t key,
{
int ret;
uint32_t kid[2];
+ uint8_t master_id[GNUTLS_OPENPGP_KEYID_SIZE];
if (!key)
{
@@ -1076,6 +1097,12 @@ gnutls_openpgp_crt_get_subkey_idx (gnutls_openpgp_crt_t key,
return GNUTLS_E_INVALID_REQUEST;
}
+ ret = gnutls_openpgp_crt_get_key_id (key, master_id);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+ if (memcmp(master_id, keyid, GNUTLS_OPENPGP_KEYID_SIZE)==0)
+ return GNUTLS_OPENPGP_MASTER_KEYID_IDX;
+
KEYID_IMPORT (kid, keyid);
ret = _gnutls_openpgp_find_subkey_idx (key->knode, kid, 0);
@@ -1116,6 +1143,9 @@ gnutls_openpgp_crt_get_subkey_usage (gnutls_openpgp_crt_t key,
return GNUTLS_E_INVALID_REQUEST;
}
+ if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX)
+ return gnutls_openpgp_crt_get_key_usage(key, key_usage);
+
pkt = _get_public_subkey (key, idx);
if (!pkt)
return GNUTLS_E_OPENPGP_SUBKEY_ERROR;
@@ -1513,6 +1543,9 @@ gnutls_openpgp_crt_get_subkey_pk_rsa_raw (gnutls_openpgp_crt_t crt,
uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE];
int ret;
+ if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX)
+ return gnutls_openpgp_crt_get_pk_rsa_raw(crt, m, e);
+
ret = gnutls_openpgp_crt_get_subkey_id (crt, idx, keyid);
if (ret < 0)
{
@@ -1551,6 +1584,9 @@ gnutls_openpgp_crt_get_subkey_pk_dsa_raw (gnutls_openpgp_crt_t crt,
uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE];
int ret;
+ if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX)
+ return gnutls_openpgp_crt_get_pk_dsa_raw(crt, p,q, g, y);
+
ret = gnutls_openpgp_crt_get_subkey_id (crt, idx, keyid);
if (ret < 0)
{
diff --git a/lib/openpgp/privkey.c b/lib/openpgp/privkey.c
index 461aa9d0e6..9498353b04 100644
--- a/lib/openpgp/privkey.c
+++ b/lib/openpgp/privkey.c
@@ -293,20 +293,22 @@ gnutls_openpgp_privkey_get_pk_algorithm (gnutls_openpgp_privkey_t key,
int idx;
idx = gnutls_openpgp_privkey_get_subkey_idx (key, keyid);
- algo =
- gnutls_openpgp_privkey_get_subkey_pk_algorithm (key, idx, NULL);
- }
- else
- {
- pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_SECRET_KEY);
- if (pkt)
+ if (idx != GNUTLS_OPENPGP_MASTER_KEYID_IDX)
{
- if (bits)
- *bits = cdk_pk_get_nbits (pkt->pkt.secret_key->pk);
- algo = _gnutls_openpgp_get_algo (pkt->pkt.secret_key->pk->pubkey_algo);
+ algo =
+ gnutls_openpgp_privkey_get_subkey_pk_algorithm (key, idx, bits);
+ return algo;
}
}
+ pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_SECRET_KEY);
+ if (pkt)
+ {
+ if (bits)
+ *bits = cdk_pk_get_nbits (pkt->pkt.secret_key->pk);
+ algo = _gnutls_openpgp_get_algo (pkt->pkt.secret_key->pk->pubkey_algo);
+ }
+
return algo;
}
@@ -440,7 +442,6 @@ gnutls_openpgp_privkey_get_key_id (gnutls_openpgp_privkey_t key,
return 0;
}
-
/**
* gnutls_openpgp_privkey_get_subkey_count:
* @key: is an OpenPGP key
@@ -521,6 +522,9 @@ gnutls_openpgp_privkey_get_subkey_revoked_status (gnutls_openpgp_privkey_t
return GNUTLS_E_INVALID_REQUEST;
}
+ if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX)
+ return gnutls_openpgp_privkey_get_revoked_status(key);
+
pkt = _get_secret_subkey (key, idx);
if (!pkt)
return GNUTLS_E_OPENPGP_GETKEY_FAILED;
@@ -562,6 +566,9 @@ gnutls_openpgp_privkey_get_subkey_pk_algorithm (gnutls_openpgp_privkey_t key,
return GNUTLS_PK_UNKNOWN;
}
+ if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX)
+ return gnutls_openpgp_privkey_get_pk_algorithm(key, bits);
+
pkt = _get_secret_subkey (key, idx);
algo = 0;
@@ -598,6 +605,7 @@ gnutls_openpgp_privkey_get_subkey_idx (gnutls_openpgp_privkey_t key,
{
int ret;
uint32_t kid[2];
+ uint8_t master_id[GNUTLS_OPENPGP_KEYID_SIZE];
if (!key)
{
@@ -605,6 +613,12 @@ gnutls_openpgp_privkey_get_subkey_idx (gnutls_openpgp_privkey_t key,
return GNUTLS_E_INVALID_REQUEST;
}
+ ret = gnutls_openpgp_privkey_get_key_id (key, master_id);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+ if (memcmp(master_id, keyid, GNUTLS_OPENPGP_KEYID_SIZE)==0)
+ return GNUTLS_OPENPGP_MASTER_KEYID_IDX;
+
KEYID_IMPORT (kid, keyid);
ret = _gnutls_openpgp_find_subkey_idx (key->knode, kid, 1);
@@ -637,7 +651,11 @@ gnutls_openpgp_privkey_get_subkey_creation_time (gnutls_openpgp_privkey_t key,
if (!key)
return (time_t) - 1;
- pkt = _get_secret_subkey (key, idx);
+ if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX)
+ pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_SECRET_KEY);
+ else
+ pkt = _get_secret_subkey (key, idx);
+
if (pkt)
timestamp = pkt->pkt.secret_key->pk->timestamp;
else
@@ -663,18 +681,22 @@ gnutls_openpgp_privkey_get_subkey_expiration_time (gnutls_openpgp_privkey_t
key, unsigned int idx)
{
cdk_packet_t pkt;
- time_t expiredate;
+ time_t timestamp;
if (!key)
return (time_t) - 1;
- pkt = _get_secret_subkey (key, idx);
+ if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX)
+ pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_SECRET_KEY);
+ else
+ pkt = _get_secret_subkey (key, idx);
+
if (pkt)
- expiredate = pkt->pkt.secret_key->expiredate;
+ timestamp = pkt->pkt.secret_key->pk->expiredate;
else
- expiredate = 0;
+ timestamp = 0;
- return expiredate;
+ return timestamp;
}
/**
@@ -703,6 +725,9 @@ gnutls_openpgp_privkey_get_subkey_id (gnutls_openpgp_privkey_t key,
return GNUTLS_E_INVALID_REQUEST;
}
+ if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX)
+ return gnutls_openpgp_privkey_get_key_id(key, keyid);
+
pkt = _get_secret_subkey (key, idx);
if (!pkt)
return GNUTLS_E_OPENPGP_GETKEY_FAILED;
@@ -742,6 +767,9 @@ gnutls_openpgp_privkey_get_subkey_fingerprint (gnutls_openpgp_privkey_t key,
return GNUTLS_E_INVALID_REQUEST;
}
+ if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX)
+ return gnutls_openpgp_privkey_get_fingerprint(key, fpr, fprlen);
+
*fprlen = 0;
pkt = _get_secret_subkey (key, idx);
@@ -1143,7 +1171,10 @@ gnutls_openpgp_privkey_export_subkey_rsa_raw (gnutls_openpgp_privkey_t pkey,
uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE];
int ret;
- ret = gnutls_openpgp_privkey_get_subkey_id (pkey, idx, keyid);
+ if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX)
+ ret = gnutls_openpgp_privkey_get_key_id (pkey, keyid);
+ else
+ ret = gnutls_openpgp_privkey_get_subkey_id (pkey, idx, keyid);
if (ret < 0)
{
gnutls_assert ();
@@ -1183,7 +1214,11 @@ gnutls_openpgp_privkey_export_subkey_dsa_raw (gnutls_openpgp_privkey_t pkey,
uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE];
int ret;
- ret = gnutls_openpgp_privkey_get_subkey_id (pkey, idx, keyid);
+ if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX)
+ ret = gnutls_openpgp_privkey_get_key_id (pkey, keyid);
+ else
+ ret = gnutls_openpgp_privkey_get_subkey_id (pkey, idx, keyid);
+
if (ret < 0)
{
gnutls_assert ();