mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-30 16:17:02 +01: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:
parent
3f284e4050
commit
5cdad8ff00
@ -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.2 X.509 extensions
|
||||
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
|
||||
|
||||
|
||||
|
@ -1042,9 +1042,9 @@ already existing key. Key-Length will be ignored when given.
|
||||
|
||||
@item Key-Usage: @var{usage-list}
|
||||
Space or comma delimited list of key usage, allowed values are
|
||||
@samp{encrypt} and @samp{sign}. This is used to generate the keyUsage
|
||||
extension. Please make sure that the algorithm is capable of this
|
||||
usage. Default is to allow encrypt and sign.
|
||||
@samp{encrypt}, @samp{sign} and @samp{cert}. This is used to generate
|
||||
the keyUsage extension. Please make sure that the algorithm is
|
||||
capable of this usage. Default is to allow encrypt and sign.
|
||||
|
||||
@item Name-DN: @var{subject-name}
|
||||
This is the Distinguished Name (DN) of the subject in RFC-2253 format.
|
||||
|
184
sm/certreqgen.c
184
sm/certreqgen.c
@ -33,6 +33,22 @@
|
||||
%commit
|
||||
%echo done
|
||||
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,
|
||||
pNOTAFTER,
|
||||
pSIGNINGKEY,
|
||||
pHASHALGO
|
||||
pHASHALGO,
|
||||
pSUBJKEYID,
|
||||
pEXTENSION
|
||||
};
|
||||
|
||||
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_basicConstraints[] = "2.5.29.19";
|
||||
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") )
|
||||
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;
|
||||
else if ( !ascii_strcasecmp (p, "cert") )
|
||||
use |= GCRY_PK_USAGE_CERT;
|
||||
else
|
||||
{
|
||||
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 },
|
||||
{ "Signing-Key", pSIGNINGKEY },
|
||||
{ "Hash-Algo", pHASHALGO },
|
||||
{ "Subject-Key-Id", pSUBJKEYID },
|
||||
{ "Extension", pEXTENSION, 1 },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
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. */
|
||||
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,
|
||||
"\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)
|
||||
@ -1009,6 +1094,101 @@ create_request (ctrl_t ctrl,
|
||||
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
|
||||
sigkey = public;
|
||||
|
@ -187,6 +187,7 @@ static struct
|
||||
/* GnuPG extensions */
|
||||
{ "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.2", "wellKnownPrivateKey" },
|
||||
|
||||
/* Extensions used by the Bundesnetzagentur. */
|
||||
{ "1.3.6.1.4.1.8301.3.5", "validityModel" },
|
||||
|
Loading…
x
Reference in New Issue
Block a user