summaryrefslogtreecommitdiff
path: root/vendor/go.mozilla.org
diff options
context:
space:
mode:
authorPaul Holzinger <pholzing@redhat.com>2022-09-08 15:32:44 +0200
committerPaul Holzinger <pholzing@redhat.com>2022-09-09 11:58:20 +0200
commiteb28a1c08469d56494006d0f2c64933ab7078d01 (patch)
treedbacf86cf194955f34f09ec56d2df284321e2ae7 /vendor/go.mozilla.org
parent7e2f002b0751c2c24e9c243495cbc313d0c3c103 (diff)
downloadpodman-eb28a1c08469d56494006d0f2c64933ab7078d01.tar.gz
podman-eb28a1c08469d56494006d0f2c64933ab7078d01.tar.bz2
podman-eb28a1c08469d56494006d0f2c64933ab7078d01.zip
update buildah and c/common to latest
also includes bumps for c/storage and c/image Signed-off-by: Paul Holzinger <pholzing@redhat.com>
Diffstat (limited to 'vendor/go.mozilla.org')
-rw-r--r--vendor/go.mozilla.org/pkcs7/.travis.yml10
-rw-r--r--vendor/go.mozilla.org/pkcs7/README.md2
-rw-r--r--vendor/go.mozilla.org/pkcs7/ber.go44
-rw-r--r--vendor/go.mozilla.org/pkcs7/encrypt.go2
-rw-r--r--vendor/go.mozilla.org/pkcs7/sign.go8
-rw-r--r--vendor/go.mozilla.org/pkcs7/verify.go85
-rw-r--r--vendor/go.mozilla.org/pkcs7/verify_test_dsa.go182
7 files changed, 302 insertions, 31 deletions
diff --git a/vendor/go.mozilla.org/pkcs7/.travis.yml b/vendor/go.mozilla.org/pkcs7/.travis.yml
deleted file mode 100644
index eac4c1762..000000000
--- a/vendor/go.mozilla.org/pkcs7/.travis.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-language: go
-go:
- - "1.11"
- - "1.12"
- - "1.13"
- - tip
-before_install:
- - make gettools
-script:
- - make
diff --git a/vendor/go.mozilla.org/pkcs7/README.md b/vendor/go.mozilla.org/pkcs7/README.md
index bf37059c5..a55d117c6 100644
--- a/vendor/go.mozilla.org/pkcs7/README.md
+++ b/vendor/go.mozilla.org/pkcs7/README.md
@@ -1,7 +1,7 @@
# pkcs7
[![GoDoc](https://godoc.org/go.mozilla.org/pkcs7?status.svg)](https://godoc.org/go.mozilla.org/pkcs7)
-[![Build Status](https://travis-ci.org/mozilla-services/pkcs7.svg?branch=master)](https://travis-ci.org/mozilla-services/pkcs7)
+[![Build Status](https://github.com/mozilla-services/pkcs7/workflows/CI/badge.svg?branch=master&event=push)](https://github.com/mozilla-services/pkcs7/actions/workflows/ci.yml?query=branch%3Amaster+event%3Apush)
pkcs7 implements parsing and creating signed and enveloped messages.
diff --git a/vendor/go.mozilla.org/pkcs7/ber.go b/vendor/go.mozilla.org/pkcs7/ber.go
index 585256739..73da024a0 100644
--- a/vendor/go.mozilla.org/pkcs7/ber.go
+++ b/vendor/go.mozilla.org/pkcs7/ber.go
@@ -175,7 +175,7 @@ func readObject(ber []byte, offset int) (asn1Object, int, error) {
if offset > berLen {
return nil, 0, errors.New("ber2der: cannot move offset forward, end of ber data reached")
}
- hack := 0
+ indefinite := false
if l > 0x80 {
numberOfBytes := (int)(l & 0x7F)
if numberOfBytes > 4 { // int is only guaranteed to be 32bit
@@ -197,14 +197,7 @@ func readObject(ber []byte, offset int) (asn1Object, int, error) {
}
}
} else if l == 0x80 {
- // find length by searching content
- markerIndex := bytes.LastIndex(ber[offset:], []byte{0x0, 0x0})
- if markerIndex == -1 {
- return nil, 0, errors.New("ber2der: Invalid BER format")
- }
- length = markerIndex
- hack = 2
- debugprint("--> (compute length) marker found at offset: %d\n", markerIndex+offset)
+ indefinite = true
} else {
length = (int)(l)
}
@@ -220,6 +213,9 @@ func readObject(ber []byte, offset int) (asn1Object, int, error) {
debugprint("--> content end : %d\n", contentEnd)
debugprint("--> content : % X\n", ber[offset:contentEnd])
var obj asn1Object
+ if indefinite && kind == 0 {
+ return nil, 0, errors.New("ber2der: Indefinite form tag must have constructed encoding")
+ }
if kind == 0 {
obj = asn1Primitive{
tagBytes: ber[tagStart:tagEnd],
@@ -228,14 +224,25 @@ func readObject(ber []byte, offset int) (asn1Object, int, error) {
}
} else {
var subObjects []asn1Object
- for offset < contentEnd {
+ for (offset < contentEnd) || indefinite {
var subObj asn1Object
var err error
- subObj, offset, err = readObject(ber[:contentEnd], offset)
+ subObj, offset, err = readObject(ber, offset)
if err != nil {
return nil, 0, err
}
subObjects = append(subObjects, subObj)
+
+ if indefinite {
+ terminated, err := isIndefiniteTermination(ber, offset)
+ if err != nil {
+ return nil, 0, err
+ }
+
+ if terminated {
+ break
+ }
+ }
}
obj = asn1Structured{
tagBytes: ber[tagStart:tagEnd],
@@ -243,7 +250,20 @@ func readObject(ber []byte, offset int) (asn1Object, int, error) {
}
}
- return obj, contentEnd + hack, nil
+ // Apply indefinite form length with 0x0000 terminator.
+ if indefinite {
+ contentEnd = offset + 2
+ }
+
+ return obj, contentEnd, nil
+}
+
+func isIndefiniteTermination(ber []byte, offset int) (bool, error) {
+ if len(ber) - offset < 2 {
+ return false, errors.New("ber2der: Invalid BER format")
+ }
+
+ return bytes.Index(ber[offset:], []byte{0x0, 0x0}) == 0, nil
}
func debugprint(format string, a ...interface{}) {
diff --git a/vendor/go.mozilla.org/pkcs7/encrypt.go b/vendor/go.mozilla.org/pkcs7/encrypt.go
index da57ae643..6b2655708 100644
--- a/vendor/go.mozilla.org/pkcs7/encrypt.go
+++ b/vendor/go.mozilla.org/pkcs7/encrypt.go
@@ -35,7 +35,7 @@ type recipientInfo struct {
type encryptedContentInfo struct {
ContentType asn1.ObjectIdentifier
ContentEncryptionAlgorithm pkix.AlgorithmIdentifier
- EncryptedContent asn1.RawValue `asn1:"tag:0,optional,explicit"`
+ EncryptedContent asn1.RawValue `asn1:"tag:0,optional"`
}
const (
diff --git a/vendor/go.mozilla.org/pkcs7/sign.go b/vendor/go.mozilla.org/pkcs7/sign.go
index addd76383..31c3654c5 100644
--- a/vendor/go.mozilla.org/pkcs7/sign.go
+++ b/vendor/go.mozilla.org/pkcs7/sign.go
@@ -124,10 +124,10 @@ func (sd *SignedData) AddSigner(ee *x509.Certificate, pkey crypto.PrivateKey, co
// The signature algorithm used to hash the data is the one of the end-entity
// certificate.
func (sd *SignedData) AddSignerChain(ee *x509.Certificate, pkey crypto.PrivateKey, parents []*x509.Certificate, config SignerInfoConfig) error {
-// Following RFC 2315, 9.2 SignerInfo type, the distinguished name of
-// the issuer of the end-entity signer is stored in the issuerAndSerialNumber
-// section of the SignedData.SignerInfo, alongside the serial number of
-// the end-entity.
+ // Following RFC 2315, 9.2 SignerInfo type, the distinguished name of
+ // the issuer of the end-entity signer is stored in the issuerAndSerialNumber
+ // section of the SignedData.SignerInfo, alongside the serial number of
+ // the end-entity.
var ias issuerAndSerial
ias.SerialNumber = ee.SerialNumber
if len(parents) == 0 {
diff --git a/vendor/go.mozilla.org/pkcs7/verify.go b/vendor/go.mozilla.org/pkcs7/verify.go
index c8ead2362..f09e27245 100644
--- a/vendor/go.mozilla.org/pkcs7/verify.go
+++ b/vendor/go.mozilla.org/pkcs7/verify.go
@@ -18,8 +18,12 @@ func (p7 *PKCS7) Verify() (err error) {
}
// VerifyWithChain checks the signatures of a PKCS7 object.
-// If truststore is not nil, it also verifies the chain of trust of the end-entity
-// signer cert to one of the root in the truststore.
+//
+// If truststore is not nil, it also verifies the chain of trust of
+// the end-entity signer cert to one of the roots in the
+// truststore. When the PKCS7 object includes the signing time
+// authenticated attr verifies the chain at that time and UTC now
+// otherwise.
func (p7 *PKCS7) VerifyWithChain(truststore *x509.CertPool) (err error) {
if len(p7.Signers) == 0 {
return errors.New("pkcs7: Message has no signers")
@@ -32,6 +36,81 @@ func (p7 *PKCS7) VerifyWithChain(truststore *x509.CertPool) (err error) {
return nil
}
+// VerifyWithChainAtTime checks the signatures of a PKCS7 object.
+//
+// If truststore is not nil, it also verifies the chain of trust of
+// the end-entity signer cert to a root in the truststore at
+// currentTime. It does not use the signing time authenticated
+// attribute.
+func (p7 *PKCS7) VerifyWithChainAtTime(truststore *x509.CertPool, currentTime time.Time) (err error) {
+ if len(p7.Signers) == 0 {
+ return errors.New("pkcs7: Message has no signers")
+ }
+ for _, signer := range p7.Signers {
+ if err := verifySignatureAtTime(p7, signer, truststore, currentTime); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func verifySignatureAtTime(p7 *PKCS7, signer signerInfo, truststore *x509.CertPool, currentTime time.Time) (err error) {
+ signedData := p7.Content
+ ee := getCertFromCertsByIssuerAndSerial(p7.Certificates, signer.IssuerAndSerialNumber)
+ if ee == nil {
+ return errors.New("pkcs7: No certificate for signer")
+ }
+ if len(signer.AuthenticatedAttributes) > 0 {
+ // TODO(fullsailor): First check the content type match
+ var (
+ digest []byte
+ signingTime time.Time
+ )
+ err := unmarshalAttribute(signer.AuthenticatedAttributes, OIDAttributeMessageDigest, &digest)
+ if err != nil {
+ return err
+ }
+ hash, err := getHashForOID(signer.DigestAlgorithm.Algorithm)
+ if err != nil {
+ return err
+ }
+ h := hash.New()
+ h.Write(p7.Content)
+ computed := h.Sum(nil)
+ if subtle.ConstantTimeCompare(digest, computed) != 1 {
+ return &MessageDigestMismatchError{
+ ExpectedDigest: digest,
+ ActualDigest: computed,
+ }
+ }
+ signedData, err = marshalAttributes(signer.AuthenticatedAttributes)
+ if err != nil {
+ return err
+ }
+ err = unmarshalAttribute(signer.AuthenticatedAttributes, OIDAttributeSigningTime, &signingTime)
+ 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))
+ }
+ }
+ }
+ if truststore != nil {
+ _, err = verifyCertChain(ee, p7.Certificates, truststore, currentTime)
+ if err != nil {
+ return err
+ }
+ }
+ sigalg, err := getSignatureAlgorithm(signer.DigestEncryptionAlgorithm, signer.DigestAlgorithm)
+ if err != nil {
+ return err
+ }
+ return ee.CheckSignature(sigalg, signedData, signer.EncryptedDigest)
+}
+
func verifySignature(p7 *PKCS7, signer signerInfo, truststore *x509.CertPool) (err error) {
signedData := p7.Content
ee := getCertFromCertsByIssuerAndSerial(p7.Certificates, signer.IssuerAndSerialNumber)
@@ -70,7 +149,7 @@ func verifySignature(p7 *PKCS7, signer signerInfo, truststore *x509.CertPool) (e
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.NotBefore.Format(time.RFC3339))
+ ee.NotAfter.Format(time.RFC3339))
}
}
}
diff --git a/vendor/go.mozilla.org/pkcs7/verify_test_dsa.go b/vendor/go.mozilla.org/pkcs7/verify_test_dsa.go
new file mode 100644
index 000000000..1eb05bc3e
--- /dev/null
+++ b/vendor/go.mozilla.org/pkcs7/verify_test_dsa.go
@@ -0,0 +1,182 @@
+// +build go1.11 go1.12 go1.13 go1.14 go1.15
+
+package pkcs7
+
+import (
+ "crypto/x509"
+ "encoding/pem"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "testing"
+)
+
+func TestVerifyEC2(t *testing.T) {
+ fixture := UnmarshalDSATestFixture(EC2IdentityDocumentFixture)
+ p7, err := Parse(fixture.Input)
+ if err != nil {
+ t.Errorf("Parse encountered unexpected error: %v", err)
+ }
+ p7.Certificates = []*x509.Certificate{fixture.Certificate}
+ if err := p7.Verify(); err != nil {
+ t.Errorf("Verify failed with error: %v", err)
+ }
+}
+
+var EC2IdentityDocumentFixture = `
+-----BEGIN PKCS7-----
+MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAaCA
+JIAEggGmewogICJwcml2YXRlSXAiIDogIjE3Mi4zMC4wLjI1MiIsCiAgImRldnBh
+eVByb2R1Y3RDb2RlcyIgOiBudWxsLAogICJhdmFpbGFiaWxpdHlab25lIiA6ICJ1
+cy1lYXN0LTFhIiwKICAidmVyc2lvbiIgOiAiMjAxMC0wOC0zMSIsCiAgImluc3Rh
+bmNlSWQiIDogImktZjc5ZmU1NmMiLAogICJiaWxsaW5nUHJvZHVjdHMiIDogbnVs
+bCwKICAiaW5zdGFuY2VUeXBlIiA6ICJ0Mi5taWNybyIsCiAgImFjY291bnRJZCIg
+OiAiMTIxNjU5MDE0MzM0IiwKICAiaW1hZ2VJZCIgOiAiYW1pLWZjZTNjNjk2IiwK
+ICAicGVuZGluZ1RpbWUiIDogIjIwMTYtMDQtMDhUMDM6MDE6MzhaIiwKICAiYXJj
+aGl0ZWN0dXJlIiA6ICJ4ODZfNjQiLAogICJrZXJuZWxJZCIgOiBudWxsLAogICJy
+YW1kaXNrSWQiIDogbnVsbCwKICAicmVnaW9uIiA6ICJ1cy1lYXN0LTEiCn0AAAAA
+AAAxggEYMIIBFAIBATBpMFwxCzAJBgNVBAYTAlVTMRkwFwYDVQQIExBXYXNoaW5n
+dG9uIFN0YXRlMRAwDgYDVQQHEwdTZWF0dGxlMSAwHgYDVQQKExdBbWF6b24gV2Vi
+IFNlcnZpY2VzIExMQwIJAJa6SNnlXhpnMAkGBSsOAwIaBQCgXTAYBgkqhkiG9w0B
+CQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0xNjA0MDgwMzAxNDRaMCMG
+CSqGSIb3DQEJBDEWBBTuUc28eBXmImAautC+wOjqcFCBVjAJBgcqhkjOOAQDBC8w
+LQIVAKA54NxGHWWCz5InboDmY/GHs33nAhQ6O/ZI86NwjA9Vz3RNMUJrUPU5tAAA
+AAAAAA==
+-----END PKCS7-----
+-----BEGIN CERTIFICATE-----
+MIIC7TCCAq0CCQCWukjZ5V4aZzAJBgcqhkjOOAQDMFwxCzAJBgNVBAYTAlVTMRkw
+FwYDVQQIExBXYXNoaW5ndG9uIFN0YXRlMRAwDgYDVQQHEwdTZWF0dGxlMSAwHgYD
+VQQKExdBbWF6b24gV2ViIFNlcnZpY2VzIExMQzAeFw0xMjAxMDUxMjU2MTJaFw0z
+ODAxMDUxMjU2MTJaMFwxCzAJBgNVBAYTAlVTMRkwFwYDVQQIExBXYXNoaW5ndG9u
+IFN0YXRlMRAwDgYDVQQHEwdTZWF0dGxlMSAwHgYDVQQKExdBbWF6b24gV2ViIFNl
+cnZpY2VzIExMQzCCAbcwggEsBgcqhkjOOAQBMIIBHwKBgQCjkvcS2bb1VQ4yt/5e
+ih5OO6kK/n1Lzllr7D8ZwtQP8fOEpp5E2ng+D6Ud1Z1gYipr58Kj3nssSNpI6bX3
+VyIQzK7wLclnd/YozqNNmgIyZecN7EglK9ITHJLP+x8FtUpt3QbyYXJdmVMegN6P
+hviYt5JH/nYl4hh3Pa1HJdskgQIVALVJ3ER11+Ko4tP6nwvHwh6+ERYRAoGBAI1j
+k+tkqMVHuAFcvAGKocTgsjJem6/5qomzJuKDmbJNu9Qxw3rAotXau8Qe+MBcJl/U
+hhy1KHVpCGl9fueQ2s6IL0CaO/buycU1CiYQk40KNHCcHfNiZbdlx1E9rpUp7bnF
+lRa2v1ntMX3caRVDdbtPEWmdxSCYsYFDk4mZrOLBA4GEAAKBgEbmeve5f8LIE/Gf
+MNmP9CM5eovQOGx5ho8WqD+aTebs+k2tn92BBPqeZqpWRa5P/+jrdKml1qx4llHW
+MXrs3IgIb6+hUIB+S8dz8/mmO0bpr76RoZVCXYab2CZedFut7qc3WUH9+EUAH5mw
+vSeDCOUMYQR7R9LINYwouHIziqQYMAkGByqGSM44BAMDLwAwLAIUWXBlk40xTwSw
+7HX32MxXYruse9ACFBNGmdX2ZBrVNGrN9N2f6ROk0k9K
+-----END CERTIFICATE-----`
+
+func TestDSASignWithOpenSSLAndVerify(t *testing.T) {
+ content := []byte(`
+A ship in port is safe,
+but that's not what ships are built for.
+-- Grace Hopper`)
+ // write the content to a temp file
+ tmpContentFile, err := ioutil.TempFile("", "TestDSASignWithOpenSSLAndVerify_content")
+ if err != nil {
+ t.Fatal(err)
+ }
+ ioutil.WriteFile(tmpContentFile.Name(), content, 0755)
+
+ // write the signer cert to a temp file
+ tmpSignerCertFile, err := ioutil.TempFile("", "TestDSASignWithOpenSSLAndVerify_signer")
+ if err != nil {
+ t.Fatal(err)
+ }
+ ioutil.WriteFile(tmpSignerCertFile.Name(), dsaPublicCert, 0755)
+
+ // write the signer key to a temp file
+ tmpSignerKeyFile, err := ioutil.TempFile("", "TestDSASignWithOpenSSLAndVerify_key")
+ if err != nil {
+ t.Fatal(err)
+ }
+ ioutil.WriteFile(tmpSignerKeyFile.Name(), dsaPrivateKey, 0755)
+
+ tmpSignedFile, err := ioutil.TempFile("", "TestDSASignWithOpenSSLAndVerify_signature")
+ if err != nil {
+ t.Fatal(err)
+ }
+ // call openssl to sign the content
+ opensslCMD := exec.Command("openssl", "smime", "-sign", "-nodetach", "-md", "sha1",
+ "-in", tmpContentFile.Name(), "-out", tmpSignedFile.Name(),
+ "-signer", tmpSignerCertFile.Name(), "-inkey", tmpSignerKeyFile.Name(),
+ "-certfile", tmpSignerCertFile.Name(), "-outform", "PEM")
+ out, err := opensslCMD.CombinedOutput()
+ if err != nil {
+ t.Fatalf("openssl command failed with %s: %s", err, out)
+ }
+
+ // verify the signed content
+ pemSignature, err := ioutil.ReadFile(tmpSignedFile.Name())
+ if err != nil {
+ t.Fatal(err)
+ }
+ fmt.Printf("%s\n", pemSignature)
+ derBlock, _ := pem.Decode(pemSignature)
+ if derBlock == nil {
+ t.Fatalf("failed to read DER block from signature PEM %s", tmpSignedFile.Name())
+ }
+ p7, err := Parse(derBlock.Bytes)
+ if err != nil {
+ t.Fatalf("Parse encountered unexpected error: %v", err)
+ }
+ if err := p7.Verify(); err != nil {
+ t.Fatalf("Verify failed with error: %v", err)
+ }
+ os.Remove(tmpSignerCertFile.Name()) // clean up
+ os.Remove(tmpSignerKeyFile.Name()) // clean up
+ os.Remove(tmpContentFile.Name()) // clean up
+}
+
+var dsaPrivateKey = []byte(`-----BEGIN PRIVATE KEY-----
+MIIBSwIBADCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdS
+PO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVCl
+pJ+f6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith
+1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuEC/BYHPUCgYEA9+GghdabPd7L
+vKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3
+zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImo
+g9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoEFgIUfW4aPdQBn9gJZp2KuNpzgHzvfsE=
+-----END PRIVATE KEY-----`)
+
+var dsaPublicCert = []byte(`-----BEGIN CERTIFICATE-----
+MIIDOjCCAvWgAwIBAgIEPCY/UDANBglghkgBZQMEAwIFADBsMRAwDgYDVQQGEwdV
+bmtub3duMRAwDgYDVQQIEwdVbmtub3duMRAwDgYDVQQHEwdVbmtub3duMRAwDgYD
+VQQKEwdVbmtub3duMRAwDgYDVQQLEwdVbmtub3duMRAwDgYDVQQDEwdVbmtub3du
+MB4XDTE4MTAyMjEzNDMwN1oXDTQ2MDMwOTEzNDMwN1owbDEQMA4GA1UEBhMHVW5r
+bm93bjEQMA4GA1UECBMHVW5rbm93bjEQMA4GA1UEBxMHVW5rbm93bjEQMA4GA1UE
+ChMHVW5rbm93bjEQMA4GA1UECxMHVW5rbm93bjEQMA4GA1UEAxMHVW5rbm93bjCC
+AbgwggEsBgcqhkjOOAQBMIIBHwKBgQD9f1OBHXUSKVLfSpwu7OTn9hG3UjzvRADD
+Hj+AtlEmaUVdQCJR+1k9jVj6v8X1ujD2y5tVbNeBO4AdNG/yZmC3a5lQpaSfn+gE
+exAiwk+7qdf+t8Yb+DtX58aophUPBPuD9tPFHsMCNVQTWhaRMvZ1864rYdcq7/Ii
+Axmd0UgBxwIVAJdgUI8VIwvMspK5gqLrhAvwWBz1AoGBAPfhoIXWmz3ey7yrXDa4
+V7l5lK+7+jrqgvlXTAs9B4JnUVlXjrrUWU/mcQcQgYC0SRZxI+hMKBYTt88JMozI
+puE8FnqLVHyNKOCjrh4rs6Z1kW6jfwv6ITVi8ftiegEkO8yk8b6oUZCJqIPf4Vrl
+nwaSi2ZegHtVJWQBTDv+z0kqA4GFAAKBgQDCriMPbEVBoRK4SOUeFwg7+VRf4TTp
+rcOQC9IVVoCjXzuWEGrp3ZI7YWJSpFnSch4lk29RH8O0HpI/NOzKnOBtnKr782pt
+1k/bJVMH9EaLd6MKnAVjrCDMYBB0MhebZ8QHY2elZZCWoqDYAcIDOsEx+m4NLErT
+ypPnjS5M0jm1PKMhMB8wHQYDVR0OBBYEFC0Yt5XdM0Kc95IX8NQ8XRssGPx7MA0G
+CWCGSAFlAwQDAgUAAzAAMC0CFQCIgQtrZZ9hdZG1ROhR5hc8nYEmbgIUAIlgC688
+qzy/7yePTlhlpj+ahMM=
+-----END CERTIFICATE-----`)
+
+type DSATestFixture struct {
+ Input []byte
+ Certificate *x509.Certificate
+}
+
+func UnmarshalDSATestFixture(testPEMBlock string) DSATestFixture {
+ var result DSATestFixture
+ var derBlock *pem.Block
+ var pemBlock = []byte(testPEMBlock)
+ for {
+ derBlock, pemBlock = pem.Decode(pemBlock)
+ if derBlock == nil {
+ break
+ }
+ switch derBlock.Type {
+ case "PKCS7":
+ result.Input = derBlock.Bytes
+ case "CERTIFICATE":
+ result.Certificate, _ = x509.ParseCertificate(derBlock.Bytes)
+ }
+ }
+
+ return result
+}