Skip to content

Commit

Permalink
Merge branch 'main' into dependabot/go_modules/github.com/go-kit/kit-…
Browse files Browse the repository at this point in the history
…0.13.0
  • Loading branch information
dopey authored Mar 15, 2024
2 parents 2799867 + 892e417 commit ed03a84
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 12 deletions.
37 changes: 26 additions & 11 deletions scep.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ func WithLogger(logger Logger) Option {
}

// WithCACerts adds option CA certificates to the SCEP operations.
// Note: This changes the verification behavior of PKCS #7 messages. If this
// Note: This changes the verification behavior of PKCS#7 messages. If this
// option is specified, only caCerts will be used as expected signers.
func WithCACerts(caCerts []*x509.Certificate) Option {
return func(c *config) {
Expand All @@ -161,7 +161,7 @@ func WithCACerts(caCerts []*x509.Certificate) Option {
// operations.
// This option is effective when used with NewCSRRequest function. In
// this case, only certificates selected with the certsSelector will be used
// as the PKCS #7 message recipients.
// as the PKCS#7 message recipients.
func WithCertsSelector(selector CertsSelector) Option {
return func(c *config) {
c.certsSelector = selector
Expand Down Expand Up @@ -198,7 +198,7 @@ type PKIMessage struct {
Recipients []*x509.Certificate

// Signer info
SignerKey *rsa.PrivateKey
SignerKey crypto.PrivateKey
SignerCert *x509.Certificate

logger Logger
Expand Down Expand Up @@ -247,7 +247,7 @@ func ParsePKIMessage(data []byte, opts ...Option) (*PKIMessage, error) {
// signatures have an alternate means of obtaining necessary certificates.
// In SCEP case, an alternate means is to use GetCaCert request.
// Note: The https://github.com/jscep/jscep implementation logs a warning if
// no certificates were found for signers in the PKCS #7 received from the
// no certificates were found for signers in the PKCS#7 received from the
// server, but the certificates obtained from GetCaCert request are still
// used for decoding the message.
p7.Certificates = conf.caCerts
Expand Down Expand Up @@ -343,8 +343,22 @@ func (msg *PKIMessage) parseMessageType() error {
}
}

// DecryptPKIEnvelope decrypts the pkcs envelopedData inside the SCEP PKIMessage
func (msg *PKIMessage) DecryptPKIEnvelope(cert *x509.Certificate, key *rsa.PrivateKey) error {
// DecryptPKIEnvelope decrypts the PKCS#7 envelopedData inside the SCEP PKIMessage
func (msg *PKIMessage) DecryptPKIEnvelope(cert *x509.Certificate, key crypto.PrivateKey) error {
if cert == nil {
return errors.New("scep: cert must not be nil")
}
if key == nil {
return errors.New("scep: key must not be nil")
}
decrypter, ok := key.(crypto.Decrypter)
if !ok {
return errors.New("scep: private key does not implement crypto.Decrypter")
}
if _, ok := decrypter.Public().(*rsa.PublicKey); !ok {
return fmt.Errorf("scep: key.Public() returned type %T; expected *rsa.PublicKey", decrypter.Public())
}

p7, err := pkcs7.Parse(msg.p7.Content)
if err != nil {
return err
Expand Down Expand Up @@ -393,7 +407,8 @@ func (msg *PKIMessage) DecryptPKIEnvelope(cert *x509.Certificate, key *rsa.Priva
}
}

func (msg *PKIMessage) Fail(crtAuth *x509.Certificate, keyAuth *rsa.PrivateKey, info FailInfo) (*PKIMessage, error) {
// Fail returns a new PKIMessage with CertRep data indicating a failure
func (msg *PKIMessage) Fail(crtAuth *x509.Certificate, keyAuth crypto.PrivateKey, info FailInfo) (*PKIMessage, error) {
config := pkcs7.SignerInfoConfig{
ExtraSignedAttributes: []pkcs7.Attribute{
{
Expand Down Expand Up @@ -456,9 +471,9 @@ func (msg *PKIMessage) Fail(crtAuth *x509.Certificate, keyAuth *rsa.PrivateKey,
}

// Success returns a new PKIMessage with CertRep data using an already-issued certificate
func (msg *PKIMessage) Success(crtAuth *x509.Certificate, keyAuth *rsa.PrivateKey, crt *x509.Certificate) (*PKIMessage, error) {
func (msg *PKIMessage) Success(crtAuth *x509.Certificate, keyAuth crypto.PrivateKey, crt *x509.Certificate) (*PKIMessage, error) {
// check if CSRReqMessage has already been decrypted
if msg.CSRReqMessage.CSR == nil {
if msg.CSRReqMessage.CSR == nil { // TODO(hslatman): remove this; just require decryption before, so that we can make keyAuth a crypto.Signer
if err := msg.DecryptPKIEnvelope(crtAuth, keyAuth); err != nil {
return nil, err
}
Expand Down Expand Up @@ -538,7 +553,7 @@ func (msg *PKIMessage) Success(crtAuth *x509.Certificate, keyAuth *rsa.PrivateKe
return crepMsg, nil
}

// DegenerateCertificates creates degenerate certificates pkcs#7 type
// DegenerateCertificates creates degenerate certificates PKCS#7 type
func DegenerateCertificates(certs []*x509.Certificate) ([]byte, error) {
var buf bytes.Buffer
for _, cert := range certs {
Expand All @@ -551,7 +566,7 @@ func DegenerateCertificates(certs []*x509.Certificate) ([]byte, error) {
return degenerate, nil
}

// CACerts extract CA Certificate or chain from pkcs7 degenerate signed data
// CACerts extract CA Certificate or chain from PKCS#7 degenerate signed data
func CACerts(data []byte) ([]*x509.Certificate, error) {
p7, err := pkcs7.Parse(data)
if err != nil {
Expand Down
35 changes: 35 additions & 0 deletions scep_test.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package scep

import (
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"errors"
"fmt"
"io"
"math/big"
"os"
"path"
Expand Down Expand Up @@ -90,6 +92,39 @@ func TestDecryptPKIEnvelopeCSR(t *testing.T) {
}
}

func TestDecryptPKIEnvelopeDecrypter(t *testing.T) {
pkcsReq := readTestFile(t, "PKCSReq.der")
msg := testParsePKIMessage(t, pkcsReq)
cacert, cakey := loadCACredentials(t)
if err := msg.DecryptPKIEnvelope(nil, cakey); err == nil {
t.Fatal("expected error on nil cert")
}

if err := msg.DecryptPKIEnvelope(cacert, nil); err == nil {
t.Fatal("expected error on nil key")
}

if err := msg.DecryptPKIEnvelope(cacert, &notADecrypter{}); err == nil {
t.Fatal("expected error on invalid decrypter")
}

if err := msg.DecryptPKIEnvelope(cacert, &nonRSADecrypter{}); err == nil {
t.Fatal("expected error on non-RSA decrypter")
}
}

type notADecrypter struct{}

type nonRSADecrypter struct{}

func (d *nonRSADecrypter) Public() crypto.PublicKey {
return struct{}{}
}

func (d *nonRSADecrypter) Decrypt(_ io.Reader, _ []byte, _ crypto.DecrypterOpts) (plaintext []byte, err error) {
return nil, errors.New("not implemented")
}

func TestDecryptPKIEnvelopeCert(t *testing.T) {
certRep := readTestFile(t, "CertRep.der")
testParsePKIMessage(t, certRep)
Expand Down
2 changes: 1 addition & 1 deletion x509util/x509util.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ type CertificateRequest struct {
// challengePassword attribute.
//
// See https://github.com/golang/go/issues/15995
func CreateCertificateRequest(rand io.Reader, template *CertificateRequest, priv interface{}) (csr []byte, err error) {
func CreateCertificateRequest(rand io.Reader, template *CertificateRequest, priv crypto.PrivateKey) (csr []byte, err error) {
if template.ChallengePassword == "" {
// if no challenge password, return a stdlib CSR.
return x509.CreateCertificateRequest(rand, &template.CertificateRequest, priv)
Expand Down

0 comments on commit ed03a84

Please sign in to comment.