swtpm_cert: Support --ecc-curveid option to pass curve id

Implement support for passing the curve id via the --curve-id
option. Default assumes secp256r1. secp384r1 is also supported.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
This commit is contained in:
Stefan Berger 2020-04-29 19:15:30 -04:00 committed by Stefan Berger
parent 3fca79b82c
commit fbc42b8d9f
3 changed files with 41 additions and 12 deletions

View File

@ -133,7 +133,7 @@
.\" ========================================================================
.\"
.IX Title "swtpm_cert 8"
.TH swtpm_cert 8 "2020-01-27" "swtpm" ""
.TH swtpm_cert 8 "2020-04-29" "swtpm" ""
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
@ -162,12 +162,16 @@ The public key (\s-1EK\s0) in \s-1PEM\s0 format.
.IX Item "--modulus <hex digits>"
The modulus of the public key as a string of hex digits. This option
can be used in place of the \-\-pubkey option.
.IP "<\-\-ecc\-x <hex digits>>" 4
.IX Item "<--ecc-x <hex digits>>"
.IP "\fB\-\-ecc\-x <hex digits\fR>" 4
.IX Item "--ecc-x <hex digits>"
The elliptic curve parameter x as string of hex digits.
.IP "<\-\-ecc\-y <hex digits>>" 4
.IX Item "<--ecc-y <hex digits>>"
.IP "\fB\-\-ecc\-y <hex digits\fR>" 4
.IX Item "--ecc-y <hex digits>"
The elliptic curve parameter y as string of hex digits.
.IP "\fB\-\-ecc\-curveid <curve id\fR>" 4
.IX Item "--ecc-curveid <curve id>"
The elliptic curve's id. secp256r1, secp384r1, and secp521r1 are supported.
If this option is not given, secp256r1 is assumed.
.IP "\fB\-\-exponent <exponent\fR>" 4
.IX Item "--exponent <exponent>"
The exponent of the public key. By default 0x10001 is assumed.

View File

@ -32,14 +32,19 @@ The public key (EK) in PEM format.
The modulus of the public key as a string of hex digits. This option
can be used in place of the --pubkey option.
=item <--ecc-x <hex digits>>
=item B<--ecc-x <hex digits>>
The elliptic curve parameter x as string of hex digits.
=item <--ecc-y <hex digits>>
=item B<--ecc-y <hex digits>>
The elliptic curve parameter y as string of hex digits.
=item B<--ecc-curveid <curve id>>
The elliptic curve's id. secp256r1, secp384r1, and secp521r1 are supported.
If this option is not given, secp256r1 is assumed.
=item B<--exponent <exponent>>
The exponent of the public key. By default 0x10001 is assumed.

View File

@ -121,6 +121,8 @@ usage(const char *prg)
"--exponent <exponent> : The exponent of the public key\n"
"--ecc-x : ECC key x component\n"
"--ecc-y : ECC key y component\n"
"--ecc-curveid <id> : ECC curve id; secp256r1, secp384r1, secp521r1\n"
" default: secp256r1\n"
"--serial <serial number> : The certificate serial number\n"
"--days <number> : Number of days the cert is valid\n"
"--pem : Write certificate in PEM format; default is DER\n"
@ -256,7 +258,8 @@ create_rsa_from_modulus(unsigned char *modulus, unsigned int modulus_len,
static gnutls_pubkey_t
create_ecc_from_x_and_y(unsigned char *ecc_x, unsigned int ecc_x_len,
unsigned char *ecc_y, unsigned int ecc_y_len)
unsigned char *ecc_y, unsigned int ecc_y_len,
const char *ecc_curveid)
{
gnutls_pubkey_t rsa = NULL;
int err;
@ -268,6 +271,7 @@ create_ecc_from_x_and_y(unsigned char *ecc_x, unsigned int ecc_x_len,
.data = ecc_y,
.size = ecc_y_len,
};
gnutls_ecc_curve_t curve;
err = gnutls_pubkey_init(&rsa);
if (err < 0) {
@ -276,8 +280,18 @@ create_ecc_from_x_and_y(unsigned char *ecc_x, unsigned int ecc_x_len,
return NULL;
}
err = gnutls_pubkey_import_ecc_raw(rsa, GNUTLS_ECC_CURVE_SECP256R1,
&x, &y);
if (ecc_curveid == NULL || !strcmp(ecc_curveid, "secp256r1")) {
curve = GNUTLS_ECC_CURVE_SECP256R1;
} else if (!strcmp(ecc_curveid, "secp384r1")) {
curve = GNUTLS_ECC_CURVE_SECP384R1;
} else if (!strcmp(ecc_curveid, "secp521r1")) {
curve = GNUTLS_ECC_CURVE_SECP521R1;
} else {
fprintf(stderr, "Unsupported ECC curve id: %s\n", ecc_curveid);
return NULL;
}
err = gnutls_pubkey_import_ecc_raw(rsa, curve, &x, &y);
if (err < 0) {
fprintf(stderr, "Could not set x and y on ECC key : %s\n",
gnutls_strerror(err));
@ -990,6 +1004,7 @@ main(int argc, char *argv[])
int ecc_x_len = 0;
unsigned char *ecc_y_bin = NULL;
int ecc_y_len = 0;
const char *ecc_curveid = NULL;
gnutls_datum_t datum = { NULL, 0}, out = { NULL, 0};
gnutls_digest_algorithm_t hashAlgo = GNUTLS_DIG_SHA1;
unsigned long long serial = 1;
@ -1026,6 +1041,7 @@ main(int argc, char *argv[])
{"modulus", required_argument, NULL, 'm'},
{"ecc-x", required_argument, NULL, 'x'},
{"ecc-y", required_argument, NULL, 'y'},
{"ecc-curveid", required_argument, NULL, 'z'},
{"exponent", required_argument, NULL, 'e'},
{"signkey", required_argument, NULL, 's'},
{"signkey-password", required_argument, NULL, 'S'},
@ -1062,7 +1078,7 @@ main(int argc, char *argv[])
#ifdef __NetBSD__
while ((opt = getopt_long(argc, argv,
"p:m:x:y:e:s:S:T:P:Q:i:o:u:d:r:1:2:3:4:5:6:7:8:9:MaXADcvh",
"p:m:x:y:z:e:s:S:T:P:Q:i:o:u:d:r:1:2:3:4:5:6:7:8:9:MaXADcvh",
long_options, &option_index)) != -1) {
#else
while ((opt = getopt_long_only(argc, argv, "", long_options,
@ -1087,6 +1103,9 @@ main(int argc, char *argv[])
goto cleanup;
}
break;
case 'z': /* --ecc-curveid */
ecc_curveid = optarg;
break;
case 'e': /* --exponent */
exponent = strtol(optarg, NULL, 0);
if (exponent == 0) {
@ -1327,7 +1346,8 @@ main(int argc, char *argv[])
modulus_bin = NULL;
} else if (ecc_x_bin) {
pubkey = create_ecc_from_x_and_y(ecc_x_bin, ecc_x_len,
ecc_y_bin, ecc_y_len);
ecc_y_bin, ecc_y_len,
ecc_curveid);
free(ecc_x_bin);
ecc_x_bin = NULL;
free(ecc_y_bin);