Pull request: home: fix ed25519 key validation

Updates #3737.

Squashed commit of the following:

commit 61cf2c6db8f3cb0c16be39975fef1a4b5da4afda
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Mon Oct 25 19:17:56 2021 +0300

    home: fix ed25519 key validation
This commit is contained in:
Ainar Garipov 2021-10-25 19:27:22 +03:00
parent 3ebac37d51
commit 6bff1d365a
2 changed files with 16 additions and 5 deletions

View File

@ -118,6 +118,7 @@ In this release, the schema version has changed from 10 to 12.
### Fixed ### Fixed
- ED25519 private key validation ([#3737]).
- Incorrect assignment of explicitly configured DHCP options ([#3744]). - Incorrect assignment of explicitly configured DHCP options ([#3744]).
- Occasional panic during shutdown ([#3655]). - Occasional panic during shutdown ([#3655]).
- Addition of IPs into only one as opposed to all matching ipsets on Linux - Addition of IPs into only one as opposed to all matching ipsets on Linux

View File

@ -4,6 +4,7 @@ import (
"context" "context"
"crypto" "crypto"
"crypto/ecdsa" "crypto/ecdsa"
"crypto/ed25519"
"crypto/rsa" "crypto/rsa"
"crypto/tls" "crypto/tls"
"crypto/x509" "crypto/x509"
@ -464,6 +465,7 @@ func validatePkey(data *tlsConfigStatus, pkey string) error {
_, keytype, err := parsePrivateKey(key.Bytes) _, keytype, err := parsePrivateKey(key.Bytes)
if err != nil { if err != nil {
data.WarningValidation = fmt.Sprintf("Failed to parse private key: %s", err) data.WarningValidation = fmt.Sprintf("Failed to parse private key: %s", err)
return errors.Error(data.WarningValidation) return errors.Error(data.WarningValidation)
} }
@ -509,23 +511,31 @@ func validateCertificates(certChain, pkey, serverName string) tlsConfigStatus {
// Attempt to parse the given private key DER block. OpenSSL 0.9.8 generates // Attempt to parse the given private key DER block. OpenSSL 0.9.8 generates
// PKCS#1 private keys by default, while OpenSSL 1.0.0 generates PKCS#8 keys. // PKCS#1 private keys by default, while OpenSSL 1.0.0 generates PKCS#8 keys.
// OpenSSL ecparam generates SEC1 EC private keys for ECDSA. We try all three. // OpenSSL ecparam generates SEC1 EC private keys for ECDSA. We try all three.
func parsePrivateKey(der []byte) (crypto.PrivateKey, string, error) { //
if key, err := x509.ParsePKCS1PrivateKey(der); err == nil { // TODO(a.garipov): Find out if this version of parsePrivateKey from the stdlib
// is actually necessary.
func parsePrivateKey(der []byte) (key crypto.PrivateKey, typ string, err error) {
if key, err = x509.ParsePKCS1PrivateKey(der); err == nil {
return key, "RSA", nil return key, "RSA", nil
} }
if key, err := x509.ParsePKCS8PrivateKey(der); err == nil { if key, err = x509.ParsePKCS8PrivateKey(der); err == nil {
switch key := key.(type) { switch key := key.(type) {
case *rsa.PrivateKey: case *rsa.PrivateKey:
return key, "RSA", nil return key, "RSA", nil
case *ecdsa.PrivateKey: case *ecdsa.PrivateKey:
return key, "ECDSA", nil return key, "ECDSA", nil
case ed25519.PrivateKey:
return key, "ED25519", nil
default: default:
return nil, "", errors.Error("tls: found unknown private key type in PKCS#8 wrapping") return nil, "", fmt.Errorf(
"tls: found unknown private key type %T in PKCS#8 wrapping",
key,
)
} }
} }
if key, err := x509.ParseECPrivateKey(der); err == nil { if key, err = x509.ParseECPrivateKey(der); err == nil {
return key, "ECDSA", nil return key, "ECDSA", nil
} }