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/", "ACVPServer": "https://demo.acvts.nist.gov/",
"CertPEMFile": "certificate_from_nist.pem", "CertPEMFile": "certificate_from_nist.pem",
"PrivateKeyDERFile": "your_private_key.key", "PrivateKeyFile": "your_private_key.key",
"TOTPSecret": "<base64 from NIST goes here>", "TOTPSecret": "<base64 from NIST goes here>",
"SessionTokensCache": "~/.cache/acvp-session-tokens", "SessionTokensCache": "~/.cache/acvp-session-tokens",
"LogFile": "log" "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`. 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 ( import (
"bufio" "bufio"
"bytes" "bytes"
"crypto"
"crypto/hmac" "crypto/hmac"
"crypto/sha256" "crypto/sha256"
"crypto/x509" "crypto/x509"
@ -51,6 +52,7 @@ var (
type Config struct { type Config struct {
CertPEMFile string CertPEMFile string
PrivateKeyFile string
PrivateKeyDERFile string PrivateKeyDERFile string
TOTPSecret string TOTPSecret string
ACVPServer string ACVPServer string
@ -281,17 +283,35 @@ func main() {
block, _ := pem.Decode(certPEM) block, _ := pem.Decode(certPEM)
certDER := block.Bytes certDER := block.Bytes
if len(config.PrivateKeyDERFile) == 0 { if len(config.PrivateKeyDERFile) == 0 && len(config.PrivateKeyFile) == 0 {
log.Fatal("Config file missing PrivateKeyDERFile") log.Fatal("Config file missing PrivateKeyDERFile and PrivateKeyFile")
} }
keyDER, err := ioutil.ReadFile(config.PrivateKeyDERFile) if len(config.PrivateKeyDERFile) != 0 && len(config.PrivateKeyFile) != 0 {
if err != nil { log.Fatal("Config file has both PrivateKeyDERFile and PrivateKeyFile. Can only have one.")
log.Fatalf("failed to read private key from %q: %s", config.PrivateKeyDERFile, err) }
privateKeyFile := config.PrivateKeyDERFile
if len(config.PrivateKeyFile) > 0 {
privateKeyFile = config.PrivateKeyFile
} }
certKey, err := x509.ParsePKCS1PrivateKey(keyDER) keyBytes, err := ioutil.ReadFile(privateKeyFile)
if err != nil { 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 var middle Middle

Loading…
Cancel
Save