rsa/pkg/inspect/csr.go

104 lines
2.1 KiB
Go

package inspect
import (
"crypto/rsa"
"crypto/x509"
"errors"
)
// DERCSRInfo attempts to parse a DER-form X.509 CSR and returns information
// about it.
func DERCSRInfo(loc string, der []byte) Info {
csr, err := x509.ParseCertificateRequest(der)
if err != nil {
return &BadInfo{
Typ: TypeX509CSR,
Loc: loc,
Underlying: err,
}
}
return CSRInfo(loc, csr)
}
// CSRInfo returns information about a CSR. Note it holds a reference to the
// csr argument.
func CSRInfo(loc string, csr *x509.CertificateRequest) Info {
key, ok := csr.PublicKey.(*rsa.PublicKey)
if !ok {
return &BadInfo{
Typ: TypeX509CSR,
Loc: loc,
Underlying: errors.New("CSR public key is not RSA"),
}
}
return &CSR{
Loc: loc,
CSR: csr,
Public: PublicKeyInfo(loc, key),
}
}
// CSR holds structured information about a CSR. It implements Info.
type CSR struct {
// Loc is the location the CSR was encountered.
Loc string
// CSR is the raw CSR.
CSR *x509.CertificateRequest
// Public holds information about the public portion of the key.
Public *PublicKey
}
// Type indicates this is a private key.
func (csr *CSR) Type() Type {
return TypeX509CSR
}
// Location returns the location data stored by PrivateKeyInfo.
func (csr *CSR) Location() string {
return csr.Loc
}
// Info returns structured information about the prvate key.
func (csr *CSR) Info() []Section {
return []Section{
csr.SubjectSection(),
csr.Public.PublicKeyInfoSection(),
}
}
// SubjectSection returns information about the subject.
func (csr *CSR) SubjectSection() Section {
f := []Field{
Field{
Key: "Description",
Value: csr.CSR.Subject.CommonName,
},
}
f = appendX509DNField(f, csr.CSR.Subject)
if len(csr.CSR.DNSNames) > 0 {
f = append(f, Field{
Key: "Hostnames",
Value: csr.CSR.DNSNames,
})
}
if len(csr.CSR.IPAddresses) > 0 {
var ips []string
for _, ip := range csr.CSR.IPAddresses {
ips = append(ips, ip.String())
}
f = append(f, Field{
Key: "IP addresses",
Value: ips,
})
}
return Section{
Title: "Subject",
Fields: f,
}
}