certlib: update FileKind with algo information.
Additionally, key algo wasn't being set on PEM files.
This commit is contained in:
@@ -3,6 +3,11 @@ package certlib
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto"
|
"crypto"
|
||||||
|
"crypto/dsa"
|
||||||
|
"crypto/ecdsa"
|
||||||
|
"crypto/ed25519"
|
||||||
|
"crypto/elliptic"
|
||||||
|
"crypto/rsa"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
"errors"
|
"errors"
|
||||||
@@ -155,16 +160,102 @@ func (f FileFormat) String() string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type KeyAlgo struct {
|
||||||
|
Type x509.PublicKeyAlgorithm
|
||||||
|
Size int
|
||||||
|
curve elliptic.Curve
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ka KeyAlgo) String() string {
|
||||||
|
switch ka.Type {
|
||||||
|
case x509.RSA:
|
||||||
|
return fmt.Sprintf("RSA-%d", ka.Size)
|
||||||
|
case x509.ECDSA:
|
||||||
|
return fmt.Sprintf("ECDSA-%s", ka.curve.Params().Name)
|
||||||
|
case x509.Ed25519:
|
||||||
|
return "Ed25519"
|
||||||
|
case x509.DSA:
|
||||||
|
return "DSA"
|
||||||
|
default:
|
||||||
|
return "unknown"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func publicKeyAlgoFromPublicKey(key crypto.PublicKey) KeyAlgo {
|
||||||
|
switch key := key.(type) {
|
||||||
|
case *rsa.PublicKey:
|
||||||
|
return KeyAlgo{
|
||||||
|
Type: x509.RSA,
|
||||||
|
Size: key.N.BitLen(),
|
||||||
|
}
|
||||||
|
case *ecdsa.PublicKey:
|
||||||
|
return KeyAlgo{
|
||||||
|
Type: x509.ECDSA,
|
||||||
|
curve: key.Curve,
|
||||||
|
Size: key.Params().BitSize,
|
||||||
|
}
|
||||||
|
case *ed25519.PublicKey:
|
||||||
|
return KeyAlgo{
|
||||||
|
Type: x509.Ed25519,
|
||||||
|
}
|
||||||
|
case *dsa.PublicKey:
|
||||||
|
return KeyAlgo{
|
||||||
|
Type: x509.DSA,
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return KeyAlgo{
|
||||||
|
Type: x509.UnknownPublicKeyAlgorithm,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func publicKeyAlgoFromKey(key crypto.PrivateKey) KeyAlgo {
|
||||||
|
switch key := key.(type) {
|
||||||
|
case *rsa.PrivateKey:
|
||||||
|
return KeyAlgo{
|
||||||
|
Type: x509.RSA,
|
||||||
|
Size: key.PublicKey.N.BitLen(),
|
||||||
|
}
|
||||||
|
case *ecdsa.PrivateKey:
|
||||||
|
return KeyAlgo{
|
||||||
|
Type: x509.ECDSA,
|
||||||
|
curve: key.PublicKey.Curve,
|
||||||
|
Size: key.Params().BitSize,
|
||||||
|
}
|
||||||
|
case *ed25519.PrivateKey:
|
||||||
|
return KeyAlgo{
|
||||||
|
Type: x509.Ed25519,
|
||||||
|
}
|
||||||
|
case *dsa.PrivateKey:
|
||||||
|
return KeyAlgo{
|
||||||
|
Type: x509.DSA,
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return KeyAlgo{
|
||||||
|
Type: x509.UnknownPublicKeyAlgorithm,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func publicKeyAlgoFromCert(cert *x509.Certificate) KeyAlgo {
|
||||||
|
return publicKeyAlgoFromPublicKey(cert.PublicKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
func publicKeyAlgoFromCSR(csr *x509.CertificateRequest) KeyAlgo {
|
||||||
|
return publicKeyAlgoFromPublicKey(csr.PublicKeyAlgorithm)
|
||||||
|
}
|
||||||
|
|
||||||
type FileType struct {
|
type FileType struct {
|
||||||
Format FileFormat
|
Format FileFormat
|
||||||
Type string
|
Type string
|
||||||
|
Algo KeyAlgo
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ft FileType) String() string {
|
func (ft FileType) String() string {
|
||||||
if ft.Type == "" {
|
if ft.Type == "" {
|
||||||
return ft.Format.String()
|
return ft.Format.String()
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("%s (%s)", ft.Type, ft.Format)
|
return fmt.Sprintf("%s %s (%s)", ft.Algo, ft.Type, ft.Format)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FileKind returns the file type of the given file.
|
// FileKind returns the file type of the given file.
|
||||||
@@ -174,36 +265,31 @@ func FileKind(path string) (*FileType, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ft := &FileType{Format: FormatDER}
|
||||||
|
|
||||||
block, _ := pem.Decode(data)
|
block, _ := pem.Decode(data)
|
||||||
if block != nil {
|
if block != nil {
|
||||||
return &FileType{
|
data = block.Bytes
|
||||||
Format: FormatPEM,
|
ft.Type = strings.ToLower(block.Type)
|
||||||
Type: strings.ToLower(strings.TrimSpace(block.Type)),
|
ft.Format = FormatPEM
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = x509.ParseCertificate(data)
|
cert, err := x509.ParseCertificate(data)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return &FileType{
|
ft.Algo = publicKeyAlgoFromCert(cert)
|
||||||
Format: FormatDER,
|
return ft, nil
|
||||||
Type: strings.ToLower(pemTypeCertificate),
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = x509.ParseCertificateRequest(data)
|
csr, err := x509.ParseCertificateRequest(data)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return &FileType{
|
ft.Algo = publicKeyAlgoFromCSR(csr)
|
||||||
Format: FormatDER,
|
return ft, nil
|
||||||
Type: strings.ToLower(pemTypeCertificateRequest),
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = x509.ParsePKCS8PrivateKey(data)
|
priv, err := x509.ParsePKCS8PrivateKey(data)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return &FileType{
|
ft.Algo = publicKeyAlgoFromKey(priv)
|
||||||
Format: FormatDER,
|
return ft, nil
|
||||||
Type: strings.ToLower(pemTypePrivateKey),
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, errors.New("certlib; unknown file type")
|
return nil, errors.New("certlib; unknown file type")
|
||||||
|
|||||||
@@ -2,7 +2,10 @@
|
|||||||
package certlib
|
package certlib
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/elliptic"
|
||||||
|
"crypto/x509"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.wntrmute.dev/kyle/goutils/assert"
|
"git.wntrmute.dev/kyle/goutils/assert"
|
||||||
@@ -138,3 +141,33 @@ func TestReadCertificates(t *testing.T) {
|
|||||||
assert.BoolT(t, cert != nil, "lib: expected an actual certificate to have been returned")
|
assert.BoolT(t, cert != nil, "lib: expected an actual certificate to have been returned")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
ecTestCACert = "testdata/ec-ca-cert.pem"
|
||||||
|
ecTestCAPriv = "testdata/ec-ca-priv.pem"
|
||||||
|
ecTestCAReq = "testdata/ec-ca-cert.csr"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestFileTypeEC(t *testing.T) {
|
||||||
|
ft, err := FileKind(ecTestCAPriv)
|
||||||
|
assert.NoErrorT(t, err)
|
||||||
|
|
||||||
|
if ft.Format != FormatPEM {
|
||||||
|
t.Errorf("certlib: expected format '%s', got '%s'", FormatPEM, ft.Format)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ft.Type != strings.ToLower(pemTypePrivateKey) {
|
||||||
|
t.Errorf("certlib: expected type '%s', got '%s'",
|
||||||
|
strings.ToLower(pemTypePrivateKey), ft.Type)
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedAlgo := KeyAlgo{
|
||||||
|
Type: x509.ECDSA,
|
||||||
|
Size: 521,
|
||||||
|
curve: elliptic.P521(),
|
||||||
|
}
|
||||||
|
|
||||||
|
if ft.Algo.String() != expectedAlgo.String() {
|
||||||
|
t.Errorf("certlib: expected algo '%s', got '%s'", expectedAlgo, ft.Algo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
12
certlib/testdata/ec-ca-cert.csr
vendored
Normal file
12
certlib/testdata/ec-ca-cert.csr
vendored
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
-----BEGIN CERTIFICATE REQUEST-----
|
||||||
|
MIIBzTCCAS4CAQAwgYgxCzAJBgNVBAYTAlVTMQkwBwYDVQQIEwAxCTAHBgNVBAcT
|
||||||
|
ADEiMCAGA1UEChMZV05UUk1VVEUgSEVBVlkgSU5EVVNUUklFUzEfMB0GA1UECxMW
|
||||||
|
Q1JZUFRPR1JBUEhJQyBTRVJWSUNFUzEeMBwGA1UEAxMVV05UUk1VVEUgVEVTVCBF
|
||||||
|
QyBDQSAxMIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQAQxmTxzo1XOK0HDrtn92b
|
||||||
|
exC4sXr8GnU+oATiXied3e1AWVOux9XtaWduY+a+r6Kb1rxMVyebn9KqtwNw+9KS
|
||||||
|
XaEB1IN9QzfdxEcJgRIAVtFplOqCip5xKK0B+woo3wXm3ndq2kJts86aONqQ0m2g
|
||||||
|
RrsmAKAX4pwmMnAHFF7veBcpsqugADAKBggqhkjOPQQDBAOBjAAwgYgCQgDG8Hdu
|
||||||
|
FkC3z0u0MU01+Bi/2MorcVTvdkurLm6Rh2Zf65aaXK8PDdV/cPZ98qx7NoLDSvwF
|
||||||
|
83gJuUI/3nVB/Ith7wJCAb6SAkXroT7y41XHayyTYb6+RKSlxxb9e5rtVCp/nG23
|
||||||
|
s59r23vUC/wDb4VWJE5jKi5vmXfjY+RAL9FOnpr2wsX0
|
||||||
|
-----END CERTIFICATE REQUEST-----
|
||||||
18
certlib/testdata/ec-ca-cert.pem
vendored
Normal file
18
certlib/testdata/ec-ca-cert.pem
vendored
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIC4TCCAkKgAwIBAgIUSnrCuvU8kj0nxNzmTgibiPLrQ8QwCgYIKoZIzj0EAwQw
|
||||||
|
gYgxCzAJBgNVBAYTAlVTMQkwBwYDVQQIEwAxCTAHBgNVBAcTADEiMCAGA1UEChMZ
|
||||||
|
V05UUk1VVEUgSEVBVlkgSU5EVVNUUklFUzEfMB0GA1UECxMWQ1JZUFRPR1JBUEhJ
|
||||||
|
QyBTRVJWSUNFUzEeMBwGA1UEAxMVV05UUk1VVEUgVEVTVCBFQyBDQSAxMB4XDTI1
|
||||||
|
MTExOTIwNTgwMVoXDTQ1MTExNDIxNTgwMVowgYgxCzAJBgNVBAYTAlVTMQkwBwYD
|
||||||
|
VQQIEwAxCTAHBgNVBAcTADEiMCAGA1UEChMZV05UUk1VVEUgSEVBVlkgSU5EVVNU
|
||||||
|
UklFUzEfMB0GA1UECxMWQ1JZUFRPR1JBUEhJQyBTRVJWSUNFUzEeMBwGA1UEAxMV
|
||||||
|
V05UUk1VVEUgVEVTVCBFQyBDQSAxMIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQA
|
||||||
|
QxmTxzo1XOK0HDrtn92bexC4sXr8GnU+oATiXied3e1AWVOux9XtaWduY+a+r6Kb
|
||||||
|
1rxMVyebn9KqtwNw+9KSXaEB1IN9QzfdxEcJgRIAVtFplOqCip5xKK0B+woo3wXm
|
||||||
|
3ndq2kJts86aONqQ0m2gRrsmAKAX4pwmMnAHFF7veBcpsqujRTBDMA4GA1UdDwEB
|
||||||
|
/wQEAwICBDASBgNVHRMBAf8ECDAGAQH/AgEDMB0GA1UdDgQWBBSNqRkvwUgIHGa2
|
||||||
|
jKmA2Q3w6Ju/FzAKBggqhkjOPQQDBAOBjAAwgYgCQgCckIFCjzJExxbV9dqm92nr
|
||||||
|
safC3kqhCxjmilf0IYWVj5f1kymoFr3jPpmy0iFcteUk0QTcqpnUT4i140lxtyK8
|
||||||
|
NAJCAVxbicZgVns9rgp6hu14l81j0XMpNgzy0QxscjMpWS/17iDJ4Y5vCWpwekrr
|
||||||
|
F1cmmRpsodONacAvTml4ehKE2ekx
|
||||||
|
-----END CERTIFICATE-----
|
||||||
8
certlib/testdata/ec-ca-priv.pem
vendored
Normal file
8
certlib/testdata/ec-ca-priv.pem
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIHuAgEAMBAGByqGSM49AgEGBSuBBAAjBIHWMIHTAgEBBEIAzkf/rvLGJBTVHHHr
|
||||||
|
lUhzsRJZgkyzSY5YE3KBReDyFWc+OB48C1gdYB1u7+PxgyfwYACjPx2y1AxN8fJh
|
||||||
|
XonY39mhgYkDgYYABABDGZPHOjVc4rQcOu2f3Zt7ELixevwadT6gBOJeJ53d7UBZ
|
||||||
|
U67H1e1pZ25j5r6vopvWvExXJ5uf0qq3A3D70pJdoQHUg31DN93ERwmBEgBW0WmU
|
||||||
|
6oKKnnEorQH7CijfBebed2raQm2zzpo42pDSbaBGuyYAoBfinCYycAcUXu94Fymy
|
||||||
|
qw==
|
||||||
|
-----END PRIVATE KEY-----
|
||||||
13
certlib/testdata/ec-ca.yaml
vendored
Normal file
13
certlib/testdata/ec-ca.yaml
vendored
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
key:
|
||||||
|
algorithm: ecdsa
|
||||||
|
size: 521
|
||||||
|
subject:
|
||||||
|
common_name: WNTRMUTE TEST EC CA 1
|
||||||
|
country: US
|
||||||
|
organization: WNTRMUTE HEAVY INDUSTRIES
|
||||||
|
organizational_unit: CRYPTOGRAPHIC SERVICES
|
||||||
|
profile:
|
||||||
|
is_ca: true
|
||||||
|
path_len: 3
|
||||||
|
key_uses: cert sign
|
||||||
|
expiry: 20y
|
||||||
8
certlib/testdata/rsa-ca-cert.csr
vendored
Normal file
8
certlib/testdata/rsa-ca-cert.csr
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
-----BEGIN CERTIFICATE REQUEST-----
|
||||||
|
MIIBCjCBvQIBADCBiTELMAkGA1UEBhMCVVMxCTAHBgNVBAgTADEJMAcGA1UEBxMA
|
||||||
|
MSIwIAYDVQQKExlXTlRSTVVURSBIRUFWWSBJTkRVU1RSSUVTMR8wHQYDVQQLExZD
|
||||||
|
UllQVE9HUkFQSElDIFNFUlZJQ0VTMR8wHQYDVQQDExZXTlRSTVVURSBURVNUIFJT
|
||||||
|
QSBDQSAxMCowBQYDK2VwAyEA1Lai2WChuUH2kq4LWddp6TlcmpuuBz6G43e9efsZ
|
||||||
|
GBqgADAFBgMrZXADQQDbBl1gW07c0g9UQmK2g8QkVIXzr2TLrOjXVAptlcW/3rPO
|
||||||
|
M3iQM2mGwZWMwv7t6C4C7xBaLcUkcqT3b4S+MaUK
|
||||||
|
-----END CERTIFICATE REQUEST-----
|
||||||
14
certlib/testdata/rsa-ca-cert.pem
vendored
Normal file
14
certlib/testdata/rsa-ca-cert.pem
vendored
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIICHDCCAc6gAwIBAgIVAN1AKHhLNsqcBEKYCqgjEMG65hhvMAUGAytlcDCBiTEL
|
||||||
|
MAkGA1UEBhMCVVMxCTAHBgNVBAgTADEJMAcGA1UEBxMAMSIwIAYDVQQKExlXTlRS
|
||||||
|
TVVURSBIRUFWWSBJTkRVU1RSSUVTMR8wHQYDVQQLExZDUllQVE9HUkFQSElDIFNF
|
||||||
|
UlZJQ0VTMR8wHQYDVQQDExZXTlRSTVVURSBURVNUIFJTQSBDQSAxMB4XDTI1MTEx
|
||||||
|
OTIxMDQyNVoXDTQ1MTExNDIyMDQyNVowgYkxCzAJBgNVBAYTAlVTMQkwBwYDVQQI
|
||||||
|
EwAxCTAHBgNVBAcTADEiMCAGA1UEChMZV05UUk1VVEUgSEVBVlkgSU5EVVNUUklF
|
||||||
|
UzEfMB0GA1UECxMWQ1JZUFRPR1JBUEhJQyBTRVJWSUNFUzEfMB0GA1UEAxMWV05U
|
||||||
|
Uk1VVEUgVEVTVCBSU0EgQ0EgMTAqMAUGAytlcAMhANS2otlgoblB9pKuC1nXaek5
|
||||||
|
XJqbrgc+huN3vXn7GRgao0UwQzAOBgNVHQ8BAf8EBAMCAgQwEgYDVR0TAQH/BAgw
|
||||||
|
BgEB/wIBAzAdBgNVHQ4EFgQUetUgY5rlFq+OCeYe0Eqmp8Ek488wBQYDK2VwA0EA
|
||||||
|
LIFZo6FQL+8q8h66Bm7favIh2AlqsXA45DpRUN2LpjNm/7NbTPDw52y8cLegUUMc
|
||||||
|
UhDyk20fGg5g6cLywC0mDA==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
3
certlib/testdata/rsa-ca-priv.pem
vendored
Normal file
3
certlib/testdata/rsa-ca-priv.pem
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MC4CAQAwBQYDK2VwBCIEIDDkYbIZKArACSevxtX2Rr8MQSeJ4Jz0qJEe/YgHfjzo
|
||||||
|
-----END PRIVATE KEY-----
|
||||||
13
certlib/testdata/rsa-ca.yaml
vendored
Normal file
13
certlib/testdata/rsa-ca.yaml
vendored
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
key:
|
||||||
|
algorithm: ed25519
|
||||||
|
size: 4096
|
||||||
|
subject:
|
||||||
|
common_name: WNTRMUTE TEST RSA CA 1
|
||||||
|
country: US
|
||||||
|
organization: WNTRMUTE HEAVY INDUSTRIES
|
||||||
|
organizational_unit: CRYPTOGRAPHIC SERVICES
|
||||||
|
profile:
|
||||||
|
is_ca: true
|
||||||
|
path_len: 3
|
||||||
|
key_uses: cert sign
|
||||||
|
expiry: 20y
|
||||||
Reference in New Issue
Block a user