aboutsummaryrefslogtreecommitdiffstats
path: root/sm/certreqgen.c
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2015-10-28 17:57:53 +0000
committerWerner Koch <[email protected]>2015-10-28 17:57:53 +0000
commit8b6c83dcb086ef09b2676e4d5b0111c88b7b8bf8 (patch)
treeac1a9e71679fd11d3f769bbeb6bc67b6e29cf3ea /sm/certreqgen.c
parentdoc: Document some changed default options. (diff)
downloadgnupg-8b6c83dcb086ef09b2676e4d5b0111c88b7b8bf8.tar.gz
gnupg-8b6c83dcb086ef09b2676e4d5b0111c88b7b8bf8.zip
sm: Allow combination of usage flags --gen-key.
* sm/certreqgen.c (create_request): Re-implement building of the key-usage extension. -- GnuPG-bug-id: 2029 Signed-off-by: Werner Koch <[email protected]>
Diffstat (limited to 'sm/certreqgen.c')
-rw-r--r--sm/certreqgen.c77
1 files changed, 46 insertions, 31 deletions
diff --git a/sm/certreqgen.c b/sm/certreqgen.c
index 0774591ba..2c6550c25 100644
--- a/sm/certreqgen.c
+++ b/sm/certreqgen.c
@@ -917,38 +917,53 @@ create_request (ctrl_t ctrl,
/* Set key usage flags. */
use = get_parameter_uint (para, pKEYUSAGE);
- if (use == GCRY_PK_USAGE_SIGN)
+ if (use)
{
- /* For signing only we encode the bits:
- KSBA_KEYUSAGE_DIGITAL_SIGNATURE
- KSBA_KEYUSAGE_NON_REPUDIATION */
- err = ksba_certreq_add_extension (cr, oidstr_keyUsage, 1,
- "\x03\x02\x06\xC0", 4);
- }
- else if (use == GCRY_PK_USAGE_ENCR)
- {
- /* For encrypt only we encode the bits:
- KSBA_KEYUSAGE_KEY_ENCIPHERMENT
- KSBA_KEYUSAGE_DATA_ENCIPHERMENT */
- err = ksba_certreq_add_extension (cr, oidstr_keyUsage, 1,
- "\x03\x02\x04\x30", 4);
- }
- else if (use == GCRY_PK_USAGE_CERT)
- {
- /* For certify only we encode the bits:
- KSBA_KEYUSAGE_KEY_CERT_SIGN
- KSBA_KEYUSAGE_CRL_SIGN */
- err = ksba_certreq_add_extension (cr, oidstr_keyUsage, 1,
- "\x03\x02\x01\x06", 4);
- }
- else
- err = 0; /* Both or none given: don't request one. */
- if (err)
- {
- log_error ("error setting the key usage: %s\n",
- gpg_strerror (err));
- rc = err;
- goto leave;
+ unsigned int mask, pos;
+ unsigned char der[4];
+
+ der[0] = 0x03;
+ der[1] = 0x02;
+ der[2] = 0;
+ der[3] = 0;
+ if ((use & GCRY_PK_USAGE_SIGN))
+ {
+ /* For signing only we encode the bits:
+ KSBA_KEYUSAGE_DIGITAL_SIGNATURE
+ KSBA_KEYUSAGE_NON_REPUDIATION = 0b11 -> 0b11000000 */
+ der[3] |= 0xc0;
+ }
+ if ((use & GCRY_PK_USAGE_ENCR))
+ {
+ /* For encrypt only we encode the bits:
+ KSBA_KEYUSAGE_KEY_ENCIPHERMENT
+ KSBA_KEYUSAGE_DATA_ENCIPHERMENT = 0b1100 -> 0b00110000 */
+ der[3] |= 0x30;
+ }
+ if ((use & GCRY_PK_USAGE_CERT))
+ {
+ /* For certify only we encode the bits:
+ KSBA_KEYUSAGE_KEY_CERT_SIGN
+ KSBA_KEYUSAGE_CRL_SIGN = 0b1100000 -> 0b00000110 */
+ der[3] |= 0x06;
+ }
+
+ /* Count number of unused bits. */
+ for (mask=1, pos=0; pos < 8 * sizeof mask; pos++, mask <<= 1)
+ {
+ if ((der[3] & mask))
+ break;
+ der[2]++;
+ }
+
+ err = ksba_certreq_add_extension (cr, oidstr_keyUsage, 1, der, 4);
+ if (err)
+ {
+ log_error ("error setting the key usage: %s\n",
+ gpg_strerror (err));
+ rc = err;
+ goto leave;
+ }
}