mirror of
https://github.com/emmansun/gmsm.git
synced 2025-04-26 20:26:19 +08:00
pkcs7: sync with upstream
This commit is contained in:
parent
cf6e203d06
commit
cb51b3657a
@ -5,8 +5,6 @@ import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
var encodeIndent = 0
|
||||
|
||||
type asn1Object interface {
|
||||
EncodeTo(writer *bytes.Buffer) error
|
||||
}
|
||||
@ -17,8 +15,6 @@ type asn1Structured struct {
|
||||
}
|
||||
|
||||
func (s asn1Structured) EncodeTo(out *bytes.Buffer) error {
|
||||
//fmt.Printf("%s--> tag: % X\n", strings.Repeat("| ", encodeIndent), s.tagBytes)
|
||||
encodeIndent++
|
||||
inner := new(bytes.Buffer)
|
||||
for _, obj := range s.content {
|
||||
err := obj.EncodeTo(inner)
|
||||
@ -26,7 +22,6 @@ func (s asn1Structured) EncodeTo(out *bytes.Buffer) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
encodeIndent--
|
||||
out.Write(s.tagBytes)
|
||||
encodeLength(out, inner.Len())
|
||||
out.Write(inner.Bytes())
|
||||
@ -47,10 +42,7 @@ func (p asn1Primitive) EncodeTo(out *bytes.Buffer) error {
|
||||
if err = encodeLength(out, p.length); err != nil {
|
||||
return err
|
||||
}
|
||||
//fmt.Printf("%s--> tag: % X length: %d\n", strings.Repeat("| ", encodeIndent), p.tagBytes, p.length)
|
||||
//fmt.Printf("%s--> content length: %d\n", strings.Repeat("| ", encodeIndent), len(p.content))
|
||||
out.Write(p.content)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -58,7 +50,6 @@ func ber2der(ber []byte) ([]byte, error) {
|
||||
if len(ber) == 0 {
|
||||
return nil, errors.New("ber2der: input ber is empty")
|
||||
}
|
||||
//fmt.Printf("--> ber2der: Transcoding %d bytes\n", len(ber))
|
||||
out := new(bytes.Buffer)
|
||||
|
||||
obj, _, err := readObject(ber, 0)
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
)
|
||||
|
||||
func TestBer2Der(t *testing.T) {
|
||||
t.Parallel()
|
||||
// indefinite length fixture
|
||||
ber := []byte{0x30, 0x80, 0x02, 0x01, 0x01, 0x00, 0x00}
|
||||
expected := []byte{0x30, 0x03, 0x02, 0x01, 0x01}
|
||||
@ -40,6 +41,7 @@ func TestBer2Der(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestBer2Der_Negatives(t *testing.T) {
|
||||
t.Parallel()
|
||||
fixtures := []struct {
|
||||
Input []byte
|
||||
ErrorContains string
|
||||
@ -65,6 +67,7 @@ func TestBer2Der_Negatives(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestBer2Der_NestedMultipleIndefinite(t *testing.T) {
|
||||
t.Parallel()
|
||||
// indefinite length fixture
|
||||
ber := []byte{0x30, 0x80, 0x30, 0x80, 0x02, 0x01, 0x01, 0x00, 0x00, 0x30, 0x80, 0x02, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00}
|
||||
expected := []byte{0x30, 0x0A, 0x30, 0x03, 0x02, 0x01, 0x01, 0x30, 0x03, 0x02, 0x01, 0x02}
|
||||
@ -101,6 +104,7 @@ func TestBer2Der_NestedMultipleIndefinite(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestVerifyIndefiniteLengthBer(t *testing.T) {
|
||||
t.Parallel()
|
||||
decoded := mustDecodePEM([]byte(testPKCS7))
|
||||
|
||||
_, err := ber2der(decoded)
|
||||
|
@ -11,7 +11,6 @@ import (
|
||||
"crypto/x509/pkix"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"log"
|
||||
"math/big"
|
||||
"os"
|
||||
"time"
|
||||
@ -262,7 +261,6 @@ func createTestCertificateByIssuer(name string, issuer *certKeyPair, sigAlg x509
|
||||
issuerKey = priv
|
||||
}
|
||||
|
||||
log.Println("creating cert", name, "issued by", issuerCert.Subject.CommonName, "with sigalg", sigAlg)
|
||||
switch pkey := priv.(type) {
|
||||
case *rsa.PrivateKey:
|
||||
derCert, err = smx509.CreateCertificate(rand.Reader, &template, (*x509.Certificate)(issuerCert), pkey.Public(), issuerKey)
|
||||
|
@ -76,6 +76,21 @@ func (p7 *PKCS7) verifyWithChainAtTime(truststore *smx509.CertPool, currentTime
|
||||
return nil
|
||||
}
|
||||
|
||||
// InvalidSigningTimeError is returned when the signing time attribute
|
||||
// falls outside of the signer certificate validity.
|
||||
type InvalidSigningTimeError struct {
|
||||
SigningTime time.Time
|
||||
NotBefore time.Time // NotBefore of signer
|
||||
NotAfter time.Time // NotAfter of signer
|
||||
}
|
||||
|
||||
func (e *InvalidSigningTimeError) Error() string {
|
||||
return fmt.Sprintf("pkcs7: signing time %q is outside of certificate validity %q to %q",
|
||||
e.SigningTime.Format(time.RFC3339),
|
||||
e.NotBefore.Format(time.RFC3339),
|
||||
e.NotAfter.Format(time.RFC3339))
|
||||
}
|
||||
|
||||
func verifySignature(p7 *PKCS7, signer signerInfo, truststore *smx509.CertPool, currentTime *time.Time, isDigest bool) (err error) {
|
||||
signedData := p7.Content
|
||||
ee := getCertFromCertsByIssuerAndSerial(p7.Certificates, signer.IssuerAndSerialNumber)
|
||||
@ -118,10 +133,11 @@ func verifySignature(p7 *PKCS7, signer signerInfo, truststore *smx509.CertPool,
|
||||
if err == nil {
|
||||
// signing time found, performing validity check
|
||||
if signingTime.After(ee.NotAfter) || signingTime.Before(ee.NotBefore) {
|
||||
return fmt.Errorf("pkcs7: signing time %q is outside of certificate validity %q to %q",
|
||||
signingTime.Format(time.RFC3339),
|
||||
ee.NotBefore.Format(time.RFC3339),
|
||||
ee.NotAfter.Format(time.RFC3339))
|
||||
return &InvalidSigningTimeError{
|
||||
SigningTime: signingTime,
|
||||
NotBefore: ee.NotBefore,
|
||||
NotAfter: ee.NotAfter,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,8 @@ package pkcs7
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
@ -10,6 +12,7 @@ import (
|
||||
"encoding/base64"
|
||||
"encoding/pem"
|
||||
"io/ioutil"
|
||||
"math/big"
|
||||
"os"
|
||||
"os/exec"
|
||||
"testing"
|
||||
@ -35,6 +38,104 @@ func TestVerify(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidSigningTime(t *testing.T) {
|
||||
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
if err != nil {
|
||||
t.Fatalf("failed generating ECDSA key: %v", err)
|
||||
}
|
||||
|
||||
// define certificate validity to a timeframe in the past, so that
|
||||
// the certificate itself is not valid at the time of signing.
|
||||
notBefore := time.Now().UTC().Round(time.Minute).Add(-2 * time.Hour)
|
||||
notAfter := time.Now().UTC().Round(time.Minute).Add(-1 * time.Hour)
|
||||
template := &x509.Certificate{
|
||||
SerialNumber: big.NewInt(1),
|
||||
Subject: pkix.Name{
|
||||
CommonName: "TestInvalidSigningtime",
|
||||
},
|
||||
NotBefore: notBefore,
|
||||
NotAfter: notAfter,
|
||||
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
|
||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageEmailProtection},
|
||||
}
|
||||
|
||||
der, err := smx509.CreateCertificate(rand.Reader, template, template, key.Public(), key)
|
||||
if err != nil {
|
||||
t.Fatalf("failed creating certificate: %v", err)
|
||||
}
|
||||
|
||||
cert, err := smx509.ParseCertificate(der)
|
||||
if err != nil {
|
||||
t.Fatalf("failed parsing certificate: %v", err)
|
||||
}
|
||||
|
||||
toBeSignedData, err := NewSignedData([]byte("test-invalid-signing-time"))
|
||||
if err != nil {
|
||||
t.Fatalf("failed creating signed data: %v", err)
|
||||
}
|
||||
|
||||
// add the signer cert, and add attributes, including the signing
|
||||
// time attribute, containing the current time
|
||||
if err := toBeSignedData.AddSigner(cert, key, SignerInfoConfig{}); err != nil {
|
||||
t.Fatalf("failed adding signer: %v", err)
|
||||
}
|
||||
|
||||
// finalizes the signed data
|
||||
signedData, err := toBeSignedData.Finish()
|
||||
if err != nil {
|
||||
t.Fatalf("failed signing data: %v", err)
|
||||
}
|
||||
|
||||
p7, err := Parse(signedData)
|
||||
if err != nil {
|
||||
t.Fatalf("failed parsing signed data: %v", err)
|
||||
}
|
||||
|
||||
signerCert := p7.GetOnlySigner()
|
||||
if !bytes.Equal(cert.Signature, signerCert.Signature) {
|
||||
t.Fatal("unexpected signer certificate obtained from P7 data")
|
||||
}
|
||||
|
||||
// verify without a chain (self-signed cert), at time.Now()
|
||||
now := time.Now()
|
||||
err = p7.VerifyWithChainAtTime(nil, &now)
|
||||
if err == nil {
|
||||
t.Fatal("expected verification error, but got nil")
|
||||
}
|
||||
|
||||
signingTimeErr, ok := err.(*InvalidSigningTimeError)
|
||||
if !ok {
|
||||
t.Fatalf("expected *InvalidSigningTimeError, but got %T", err)
|
||||
}
|
||||
|
||||
if signingTimeErr.NotBefore != notBefore {
|
||||
t.Errorf("expected notBefore to be %q, but got %q", notBefore, signingTimeErr.NotBefore)
|
||||
}
|
||||
|
||||
if signingTimeErr.NotAfter != notAfter {
|
||||
t.Errorf("expected notAfter to be %q, but got %q", notAfter, signingTimeErr.NotAfter)
|
||||
}
|
||||
|
||||
// verify without a chain (self-signed cert), but without specifying the time
|
||||
err = p7.VerifyWithChain(nil)
|
||||
if err == nil {
|
||||
t.Fatal("expected verification error, but got nil")
|
||||
}
|
||||
|
||||
signingTimeErr, ok = err.(*InvalidSigningTimeError)
|
||||
if !ok {
|
||||
t.Fatalf("expected *InvalidSigningTimeError, but got %T", err)
|
||||
}
|
||||
|
||||
if signingTimeErr.NotBefore != notBefore {
|
||||
t.Errorf("expected notBefore to be %q, but got %q", notBefore, signingTimeErr.NotBefore)
|
||||
}
|
||||
|
||||
if signingTimeErr.NotAfter != notAfter {
|
||||
t.Errorf("expected notAfter to be %q, but got %q", notAfter, signingTimeErr.NotAfter)
|
||||
}
|
||||
}
|
||||
|
||||
var SignedTestFixture = `
|
||||
-----BEGIN PKCS7-----
|
||||
MIIDVgYJKoZIhvcNAQcCoIIDRzCCA0MCAQExCTAHBgUrDgMCGjAcBgkqhkiG9w0B
|
||||
|
Loading…
x
Reference in New Issue
Block a user