acvp: handle more private key formats.

This change adds a config parameter PrivateKeyFile (to replace
PrivateKeyDERFile, although that still exists) because taking PKCS#1 DER
is a little odd for people. Also probe for PEM/DER and PKCS#1/8
automatically to try and work with whatever private key the user has.

Change-Id: I0f4efcd79528cfb26f791e9ee8c5141fc6a93723
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/43344
Reviewed-by: David Benjamin <davidben@google.com>
chromium-5359
Adam Langley 4 years ago committed by Adam Langley
parent 6222fe767d
commit 048f354b2a
  1. 4
      util/fipstools/acvp/ACVP.md
  2. 34
      util/fipstools/acvp/acvptool/acvp.go

@ -13,14 +13,14 @@ Configuration is done via a `config.json` file in the current working directory.
{
"ACVPServer": "https://demo.acvts.nist.gov/",
"CertPEMFile": "certificate_from_nist.pem",
"PrivateKeyDERFile": "your_private_key.key",
"PrivateKeyFile": "your_private_key.key",
"TOTPSecret": "<base64 from NIST goes here>",
"SessionTokensCache": "~/.cache/acvp-session-tokens",
"LogFile": "log"
}
```
NIST's ACVP servers use both TLS client certificates and TOTP for authentication. When registering with NIST, they'll sign a CSR and return a certificate in PEM format, which is pointed to be `CertPEMFile`. The corresponding PKCS#1, DER-encoded private key is expected in `PrivateKeyDERFile`. Lastly, NIST will provide a file that contains the base64-encoded TOTP seed, which must be pasted in as the value of `TOTPSecret`.
NIST's ACVP servers use both TLS client certificates and TOTP for authentication. When registering with NIST, they'll sign a CSR and return a certificate in PEM format, which is pointed to be `CertPEMFile`. The corresponding private key is expected in `PrivateKeyFile`. Lastly, NIST will provide a file that contains the base64-encoded TOTP seed, which must be pasted in as the value of `TOTPSecret`.
NIST's ACVP server provides special access tokens for each test session and test sessions can _only_ be accessed via those tokens. The reasoning behind this is unclear but this client can, optionally, keep records of these access tokens in the directory named by `SessionTokensCache`. If that directory name begins with `~/` then that prefix will be replaced with the value of `$HOME`.

@ -17,6 +17,7 @@ package main
import (
"bufio"
"bytes"
"crypto"
"crypto/hmac"
"crypto/sha256"
"crypto/x509"
@ -51,6 +52,7 @@ var (
type Config struct {
CertPEMFile string
PrivateKeyFile string
PrivateKeyDERFile string
TOTPSecret string
ACVPServer string
@ -281,17 +283,35 @@ func main() {
block, _ := pem.Decode(certPEM)
certDER := block.Bytes
if len(config.PrivateKeyDERFile) == 0 {
log.Fatal("Config file missing PrivateKeyDERFile")
if len(config.PrivateKeyDERFile) == 0 && len(config.PrivateKeyFile) == 0 {
log.Fatal("Config file missing PrivateKeyDERFile and PrivateKeyFile")
}
keyDER, err := ioutil.ReadFile(config.PrivateKeyDERFile)
if err != nil {
log.Fatalf("failed to read private key from %q: %s", config.PrivateKeyDERFile, err)
if len(config.PrivateKeyDERFile) != 0 && len(config.PrivateKeyFile) != 0 {
log.Fatal("Config file has both PrivateKeyDERFile and PrivateKeyFile. Can only have one.")
}
privateKeyFile := config.PrivateKeyDERFile
if len(config.PrivateKeyFile) > 0 {
privateKeyFile = config.PrivateKeyFile
}
certKey, err := x509.ParsePKCS1PrivateKey(keyDER)
keyBytes, err := ioutil.ReadFile(privateKeyFile)
if err != nil {
log.Fatalf("failed to parse private key from %q: %s", config.PrivateKeyDERFile, err)
log.Fatalf("failed to read private key from %q: %s", privateKeyFile, err)
}
var keyDER []byte
pemBlock, _ := pem.Decode(keyBytes)
if pemBlock != nil {
keyDER = pemBlock.Bytes
} else {
keyDER = keyBytes
}
var certKey crypto.PrivateKey
if certKey, err = x509.ParsePKCS1PrivateKey(keyDER); err != nil {
if certKey, err = x509.ParsePKCS8PrivateKey(keyDER); err != nil {
log.Fatalf("failed to parse private key from %q: %s", privateKeyFile, err)
}
}
var middle Middle

Loading…
Cancel
Save