1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-05-28 21:50:02 +02:00

gpgsm: Allow arbitrary extensions for cert creation.

* sm/certreqgen.c (pSUBJKEYID, pEXTENSION): New.
(read_parameters): Add new keywords.
(proc_parameters): Check values of new keywords.
(create_request): Add SubjectKeyId and extensions.
(parse_parameter_usage): Support "cert" and the encrypt alias "encr".
This commit is contained in:
Werner Koch 2011-12-06 19:57:27 +01:00
parent 3f284e4050
commit 5cdad8ff00
4 changed files with 187 additions and 5 deletions

View File

@ -1036,6 +1036,7 @@ OIDs below the GnuPG arc:
1.3.6.1.4.1.11591.2.1.1 pkaAddress 1.3.6.1.4.1.11591.2.1.1 pkaAddress
1.3.6.1.4.1.11591.2.2 X.509 extensions 1.3.6.1.4.1.11591.2.2 X.509 extensions
1.3.6.1.4.1.11591.2.2.1 standaloneCertificate 1.3.6.1.4.1.11591.2.2.1 standaloneCertificate
1.3.6.1.4.1.11591.2.2.2 wellKnownPrivateKey
1.3.6.1.4.1.11591.2.12242973 invalid encoded OID 1.3.6.1.4.1.11591.2.12242973 invalid encoded OID

View File

@ -1042,9 +1042,9 @@ already existing key. Key-Length will be ignored when given.
@item Key-Usage: @var{usage-list} @item Key-Usage: @var{usage-list}
Space or comma delimited list of key usage, allowed values are Space or comma delimited list of key usage, allowed values are
@samp{encrypt} and @samp{sign}. This is used to generate the keyUsage @samp{encrypt}, @samp{sign} and @samp{cert}. This is used to generate
extension. Please make sure that the algorithm is capable of this the keyUsage extension. Please make sure that the algorithm is
usage. Default is to allow encrypt and sign. capable of this usage. Default is to allow encrypt and sign.
@item Name-DN: @var{subject-name} @item Name-DN: @var{subject-name}
This is the Distinguished Name (DN) of the subject in RFC-2253 format. This is the Distinguished Name (DN) of the subject in RFC-2253 format.

View File

@ -33,6 +33,22 @@
%commit %commit
%echo done %echo done
EOF EOF
This parameter file was used to create the STEED CA:
Key-Type: RSA
Key-Length: 1024
Key-Grip: 68A638998DFABAC510EA645CE34F9686B2EDF7EA
Key-Usage: cert
Serial: 1
Name-DN: CN=The STEED Self-Signing Nonthority
Not-Before: 2011-11-11
Not-After: 2106-02-06
Subject-Key-Id: 68A638998DFABAC510EA645CE34F9686B2EDF7EA
Extension: 2.5.29.19 c 30060101ff020101
Extension: 1.3.6.1.4.1.11591.2.2.2 n 0101ff
Signing-Key: 68A638998DFABAC510EA645CE34F9686B2EDF7EA
%commit
*/ */
@ -68,7 +84,9 @@ enum para_name
pNOTBEFORE, pNOTBEFORE,
pNOTAFTER, pNOTAFTER,
pSIGNINGKEY, pSIGNINGKEY,
pHASHALGO pHASHALGO,
pSUBJKEYID,
pEXTENSION
}; };
struct para_data_s struct para_data_s
@ -89,6 +107,7 @@ struct reqgen_ctrl_s
}; };
static const char oidstr_subjectKeyIdentifier[] = "2.5.29.14";
static const char oidstr_keyUsage[] = "2.5.29.15"; static const char oidstr_keyUsage[] = "2.5.29.15";
static const char oidstr_basicConstraints[] = "2.5.29.19"; static const char oidstr_basicConstraints[] = "2.5.29.19";
static const char oidstr_standaloneCertificate[] = "1.3.6.1.4.1.11591.2.2.1"; static const char oidstr_standaloneCertificate[] = "1.3.6.1.4.1.11591.2.2.1";
@ -170,8 +189,11 @@ parse_parameter_usage (struct para_data_s *para, enum para_name key)
; ;
else if ( !ascii_strcasecmp (p, "sign") ) else if ( !ascii_strcasecmp (p, "sign") )
use |= GCRY_PK_USAGE_SIGN; use |= GCRY_PK_USAGE_SIGN;
else if ( !ascii_strcasecmp (p, "encrypt") ) else if ( !ascii_strcasecmp (p, "encrypt")
|| !ascii_strcasecmp (p, "encr") )
use |= GCRY_PK_USAGE_ENCR; use |= GCRY_PK_USAGE_ENCR;
else if ( !ascii_strcasecmp (p, "cert") )
use |= GCRY_PK_USAGE_CERT;
else else
{ {
log_error ("line %d: invalid usage list\n", r->lnr); log_error ("line %d: invalid usage list\n", r->lnr);
@ -225,6 +247,8 @@ read_parameters (ctrl_t ctrl, estream_t fp, estream_t out_fp)
{ "Not-After", pNOTAFTER }, { "Not-After", pNOTAFTER },
{ "Signing-Key", pSIGNINGKEY }, { "Signing-Key", pSIGNINGKEY },
{ "Hash-Algo", pHASHALGO }, { "Hash-Algo", pHASHALGO },
{ "Subject-Key-Id", pSUBJKEYID },
{ "Extension", pEXTENSION, 1 },
{ NULL, 0 } { NULL, 0 }
}; };
char line[1024], *p; char line[1024], *p;
@ -594,6 +618,59 @@ proc_parameters (ctrl_t ctrl, struct para_data_s *para,
} }
} }
/* Check the optional SubjectKeyId. */
string = get_parameter_value (para, pSUBJKEYID, 0);
if (string)
{
for (s=string, i=0; hexdigitp (s); s++, i++)
;
if (*s || (i&1))
{
r = get_parameter (para, pSUBJKEYID, 0);
log_error (_("line %d: invalid subject-key-id\n"), r->lnr);
xfree (cardkeyid);
return gpg_error (GPG_ERR_INV_PARAMETER);
}
}
/* Check the optional extensions. */
for (seq=0; (string=get_parameter_value (para, pEXTENSION, seq)); seq++)
{
int okay = 0;
s = strpbrk (string, " \t:");
if (s)
{
s++;
while (spacep (s))
s++;
if (*s && strchr ("nNcC", *s))
{
s++;
while (spacep (s))
s++;
if (*s == ':')
s++;
if (*s)
{
while (spacep (s))
s++;
for (i=0; hexdigitp (s); s++, i++)
;
if (!((*s && *s != ':') || !i || (i&1)))
okay = 1;
}
}
}
if (!okay)
{
r = get_parameter (para, pEXTENSION, seq);
log_error (_("line %d: invalid extension syntax\n"), r->lnr);
xfree (cardkeyid);
return gpg_error (GPG_ERR_INV_PARAMETER);
}
}
/* Create or retrieve the public key. */ /* Create or retrieve the public key. */
if (cardkeyid) /* Take the key from the current smart card. */ if (cardkeyid) /* Take the key from the current smart card. */
{ {
@ -838,6 +915,14 @@ create_request (ctrl_t ctrl,
err = ksba_certreq_add_extension (cr, oidstr_keyUsage, 1, err = ksba_certreq_add_extension (cr, oidstr_keyUsage, 1,
"\x03\x02\x04\x30", 4); "\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 else
err = 0; /* Both or none given: don't request one. */ err = 0; /* Both or none given: don't request one. */
if (err) if (err)
@ -1009,6 +1094,101 @@ create_request (ctrl_t ctrl,
goto leave; goto leave;
} }
} }
/* Insert the SubjectKeyId. */
string = get_parameter_value (para, pSUBJKEYID, 0);
if (string)
{
char *hexbuf;
/* Allocate a buffer for in-place conversion. We also add 2
extra bytes space for the tag and length field. */
hexbuf = xtrymalloc (2 + strlen (string) + 1);
if (!hexbuf)
{
err = gpg_error_from_syserror ();
goto leave;
}
strcpy (hexbuf+2, string);
for (p=hexbuf+2, len=0; p[0] && p[1]; p += 2)
((unsigned char*)hexbuf)[2+len++] = xtoi_2 (p);
if (len > 127)
{
err = gpg_error (GPG_ERR_TOO_LARGE);
xfree (hexbuf);
goto leave;
}
hexbuf[0] = 0x04; /* Tag for an Octet string. */
hexbuf[1] = len;
err = ksba_certreq_add_extension (cr, oidstr_subjectKeyIdentifier, 0,
hexbuf, 2+len);
xfree (hexbuf);
if (err)
{
log_error ("error setting the subject-key-id: %s\n",
gpg_strerror (err));
goto leave;
}
}
/* Insert additional extensions. */
for (seq=0; (string = get_parameter_value (para, pEXTENSION, seq)); seq++)
{
char *hexbuf;
char *oidstr;
int crit = 0;
s = strpbrk (string, " \t:");
if (!s)
{
err = gpg_error (GPG_ERR_INTERNAL);
goto leave;
}
oidstr = xtrymalloc (s - string + 1);
if (!oidstr)
{
err = gpg_error_from_syserror ();
goto leave;
}
memcpy (oidstr, string, (s-string));
oidstr[(s-string)] = 0;
s++;
while (spacep (s))
s++;
if (!*s)
{
err = gpg_error (GPG_ERR_INTERNAL);
xfree (oidstr);
goto leave;
}
if (strchr ("cC", *s))
crit = 1;
s++;
while (spacep (s))
s++;
if (*s == ':')
s++;
while (spacep (s))
s++;
hexbuf = xtrystrdup (s);
if (!hexbuf)
{
err = gpg_error_from_syserror ();
xfree (oidstr);
goto leave;
}
for (p=hexbuf, len=0; p[0] && p[1]; p += 2)
((unsigned char*)hexbuf)[len++] = xtoi_2 (p);
err = ksba_certreq_add_extension (cr, oidstr, crit,
hexbuf, len);
xfree (oidstr);
xfree (hexbuf);
}
} }
else else
sigkey = public; sigkey = public;

View File

@ -187,6 +187,7 @@ static struct
/* GnuPG extensions */ /* GnuPG extensions */
{ "1.3.6.1.4.1.11591.2.1.1", "pkaAddress" }, { "1.3.6.1.4.1.11591.2.1.1", "pkaAddress" },
{ "1.3.6.1.4.1.11591.2.2.1", "standaloneCertificate" }, { "1.3.6.1.4.1.11591.2.2.1", "standaloneCertificate" },
{ "1.3.6.1.4.1.11591.2.2.2", "wellKnownPrivateKey" },
/* Extensions used by the Bundesnetzagentur. */ /* Extensions used by the Bundesnetzagentur. */
{ "1.3.6.1.4.1.8301.3.5", "validityModel" }, { "1.3.6.1.4.1.8301.3.5", "validityModel" },