mirror of
git://git.gnupg.org/gnupg.git
synced 2025-05-19 09:02:22 +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:
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.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
|
||||||
|
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
184
sm/certreqgen.c
184
sm/certreqgen.c
@ -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;
|
||||||
|
@ -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" },
|
||||||
|
Loading…
x
Reference in New Issue
Block a user