summaryrefslogtreecommitdiff
path: root/vendor/github.com/fullsailor
diff options
context:
space:
mode:
authorTomSweeneyRedHat <tsweeney@redhat.com>2020-08-03 14:34:20 -0400
committerTomSweeneyRedHat <tsweeney@redhat.com>2020-08-03 14:34:24 -0400
commit47c91097f7b93045e9c099b52870c35577f80734 (patch)
treefd63e9de155376c5f6f8ac021045a258cf491994 /vendor/github.com/fullsailor
parent1709335cf04e947117d4ae4dca72f24f4095511b (diff)
downloadpodman-47c91097f7b93045e9c099b52870c35577f80734.tar.gz
podman-47c91097f7b93045e9c099b52870c35577f80734.tar.bz2
podman-47c91097f7b93045e9c099b52870c35577f80734.zip
Bump to Buildah 1.16.0-dev in upstream
Bump Buildah to v1.16.0-dev in the upstream branch of Podman. This will allow us to get a number of new issues into the upstream branch for use. The version of Buildah will need to be bumped to v1.16.0 and then vendored into Podman before we release Podman v2.0 Signed-off-by: TomSweeneyRedHat <tsweeney@redhat.com>
Diffstat (limited to 'vendor/github.com/fullsailor')
-rw-r--r--vendor/github.com/fullsailor/pkcs7/.gitignore24
-rw-r--r--vendor/github.com/fullsailor/pkcs7/.travis.yml7
-rw-r--r--vendor/github.com/fullsailor/pkcs7/LICENSE22
-rw-r--r--vendor/github.com/fullsailor/pkcs7/README.md8
-rw-r--r--vendor/github.com/fullsailor/pkcs7/ber.go248
-rw-r--r--vendor/github.com/fullsailor/pkcs7/pkcs7.go962
-rw-r--r--vendor/github.com/fullsailor/pkcs7/x509.go133
7 files changed, 0 insertions, 1404 deletions
diff --git a/vendor/github.com/fullsailor/pkcs7/.gitignore b/vendor/github.com/fullsailor/pkcs7/.gitignore
deleted file mode 100644
index daf913b1b..000000000
--- a/vendor/github.com/fullsailor/pkcs7/.gitignore
+++ /dev/null
@@ -1,24 +0,0 @@
-# Compiled Object files, Static and Dynamic libs (Shared Objects)
-*.o
-*.a
-*.so
-
-# Folders
-_obj
-_test
-
-# Architecture specific extensions/prefixes
-*.[568vq]
-[568vq].out
-
-*.cgo1.go
-*.cgo2.c
-_cgo_defun.c
-_cgo_gotypes.go
-_cgo_export.*
-
-_testmain.go
-
-*.exe
-*.test
-*.prof
diff --git a/vendor/github.com/fullsailor/pkcs7/.travis.yml b/vendor/github.com/fullsailor/pkcs7/.travis.yml
deleted file mode 100644
index bc1204376..000000000
--- a/vendor/github.com/fullsailor/pkcs7/.travis.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-language: go
-
-go:
- - 1.8
- - 1.9
- - "1.10"
- - tip
diff --git a/vendor/github.com/fullsailor/pkcs7/LICENSE b/vendor/github.com/fullsailor/pkcs7/LICENSE
deleted file mode 100644
index 75f320908..000000000
--- a/vendor/github.com/fullsailor/pkcs7/LICENSE
+++ /dev/null
@@ -1,22 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2015 Andrew Smith
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
diff --git a/vendor/github.com/fullsailor/pkcs7/README.md b/vendor/github.com/fullsailor/pkcs7/README.md
deleted file mode 100644
index bfd948f32..000000000
--- a/vendor/github.com/fullsailor/pkcs7/README.md
+++ /dev/null
@@ -1,8 +0,0 @@
-# pkcs7
-
-[![GoDoc](https://godoc.org/github.com/fullsailor/pkcs7?status.svg)](https://godoc.org/github.com/fullsailor/pkcs7)
-[![Build Status](https://travis-ci.org/fullsailor/pkcs7.svg?branch=master)](https://travis-ci.org/fullsailor/pkcs7)
-
-pkcs7 implements parsing and creating signed and enveloped messages.
-
-- Documentation on [GoDoc](http://godoc.org/github.com/fullsailor/pkcs7)
diff --git a/vendor/github.com/fullsailor/pkcs7/ber.go b/vendor/github.com/fullsailor/pkcs7/ber.go
deleted file mode 100644
index 89e96d30c..000000000
--- a/vendor/github.com/fullsailor/pkcs7/ber.go
+++ /dev/null
@@ -1,248 +0,0 @@
-package pkcs7
-
-import (
- "bytes"
- "errors"
-)
-
-// var encodeIndent = 0
-
-type asn1Object interface {
- EncodeTo(writer *bytes.Buffer) error
-}
-
-type asn1Structured struct {
- tagBytes []byte
- content []asn1Object
-}
-
-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)
- if err != nil {
- return err
- }
- }
- //encodeIndent--
- out.Write(s.tagBytes)
- encodeLength(out, inner.Len())
- out.Write(inner.Bytes())
- return nil
-}
-
-type asn1Primitive struct {
- tagBytes []byte
- length int
- content []byte
-}
-
-func (p asn1Primitive) EncodeTo(out *bytes.Buffer) error {
- _, err := out.Write(p.tagBytes)
- if err != nil {
- return err
- }
- 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
-}
-
-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)
- if err != nil {
- return nil, err
- }
- obj.EncodeTo(out)
-
- // if offset < len(ber) {
- // return nil, fmt.Errorf("ber2der: Content longer than expected. Got %d, expected %d", offset, len(ber))
- //}
-
- return out.Bytes(), nil
-}
-
-// encodes lengths that are longer than 127 into string of bytes
-func marshalLongLength(out *bytes.Buffer, i int) (err error) {
- n := lengthLength(i)
-
- for ; n > 0; n-- {
- err = out.WriteByte(byte(i >> uint((n-1)*8)))
- if err != nil {
- return
- }
- }
-
- return nil
-}
-
-// computes the byte length of an encoded length value
-func lengthLength(i int) (numBytes int) {
- numBytes = 1
- for i > 255 {
- numBytes++
- i >>= 8
- }
- return
-}
-
-// encodes the length in DER format
-// If the length fits in 7 bits, the value is encoded directly.
-//
-// Otherwise, the number of bytes to encode the length is first determined.
-// This number is likely to be 4 or less for a 32bit length. This number is
-// added to 0x80. The length is encoded in big endian encoding follow after
-//
-// Examples:
-// length | byte 1 | bytes n
-// 0 | 0x00 | -
-// 120 | 0x78 | -
-// 200 | 0x81 | 0xC8
-// 500 | 0x82 | 0x01 0xF4
-//
-func encodeLength(out *bytes.Buffer, length int) (err error) {
- if length >= 128 {
- l := lengthLength(length)
- err = out.WriteByte(0x80 | byte(l))
- if err != nil {
- return
- }
- err = marshalLongLength(out, length)
- if err != nil {
- return
- }
- } else {
- err = out.WriteByte(byte(length))
- if err != nil {
- return
- }
- }
- return
-}
-
-func readObject(ber []byte, offset int) (asn1Object, int, error) {
- //fmt.Printf("\n====> Starting readObject at offset: %d\n\n", offset)
- tagStart := offset
- b := ber[offset]
- offset++
- tag := b & 0x1F // last 5 bits
- if tag == 0x1F {
- tag = 0
- for ber[offset] >= 0x80 {
- tag = tag*128 + ber[offset] - 0x80
- offset++
- }
- tag = tag*128 + ber[offset] - 0x80
- offset++
- }
- tagEnd := offset
-
- kind := b & 0x20
- /*
- if kind == 0 {
- fmt.Print("--> Primitive\n")
- } else {
- fmt.Print("--> Constructed\n")
- }
- */
- // read length
- var length int
- l := ber[offset]
- offset++
- indefinite := false
- if l > 0x80 {
- numberOfBytes := (int)(l & 0x7F)
- if numberOfBytes > 4 { // int is only guaranteed to be 32bit
- return nil, 0, errors.New("ber2der: BER tag length too long")
- }
- if numberOfBytes == 4 && (int)(ber[offset]) > 0x7F {
- return nil, 0, errors.New("ber2der: BER tag length is negative")
- }
- if 0x0 == (int)(ber[offset]) {
- return nil, 0, errors.New("ber2der: BER tag length has leading zero")
- }
- //fmt.Printf("--> (compute length) indicator byte: %x\n", l)
- //fmt.Printf("--> (compute length) length bytes: % X\n", ber[offset:offset+numberOfBytes])
- for i := 0; i < numberOfBytes; i++ {
- length = length*256 + (int)(ber[offset])
- offset++
- }
- } else if l == 0x80 {
- indefinite = true
- } else {
- length = (int)(l)
- }
-
- //fmt.Printf("--> length : %d\n", length)
- contentEnd := offset + length
- if contentEnd > len(ber) {
- return nil, 0, errors.New("ber2der: BER tag length is more than available data")
- }
- //fmt.Printf("--> content start : %d\n", offset)
- //fmt.Printf("--> content end : %d\n", contentEnd)
- //fmt.Printf("--> 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],
- length: length,
- content: ber[offset:contentEnd],
- }
- } else {
- var subObjects []asn1Object
- for (offset < contentEnd) || indefinite {
- var subObj asn1Object
- var err error
- 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],
- content: subObjects,
- }
- }
-
- // 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
-}
diff --git a/vendor/github.com/fullsailor/pkcs7/pkcs7.go b/vendor/github.com/fullsailor/pkcs7/pkcs7.go
deleted file mode 100644
index 0264466b4..000000000
--- a/vendor/github.com/fullsailor/pkcs7/pkcs7.go
+++ /dev/null
@@ -1,962 +0,0 @@
-// Package pkcs7 implements parsing and generation of some PKCS#7 structures.
-package pkcs7
-
-import (
- "bytes"
- "crypto"
- "crypto/aes"
- "crypto/cipher"
- "crypto/des"
- "crypto/hmac"
- "crypto/rand"
- "crypto/rsa"
- "crypto/x509"
- "crypto/x509/pkix"
- "encoding/asn1"
- "errors"
- "fmt"
- "math/big"
- "sort"
- "time"
-
- _ "crypto/sha1" // for crypto.SHA1
-)
-
-// PKCS7 Represents a PKCS7 structure
-type PKCS7 struct {
- Content []byte
- Certificates []*x509.Certificate
- CRLs []pkix.CertificateList
- Signers []signerInfo
- raw interface{}
-}
-
-type contentInfo struct {
- ContentType asn1.ObjectIdentifier
- Content asn1.RawValue `asn1:"explicit,optional,tag:0"`
-}
-
-// ErrUnsupportedContentType is returned when a PKCS7 content is not supported.
-// Currently only Data (1.2.840.113549.1.7.1), Signed Data (1.2.840.113549.1.7.2),
-// and Enveloped Data are supported (1.2.840.113549.1.7.3)
-var ErrUnsupportedContentType = errors.New("pkcs7: cannot parse data: unimplemented content type")
-
-type unsignedData []byte
-
-var (
- oidData = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7, 1}
- oidSignedData = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7, 2}
- oidEnvelopedData = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7, 3}
- oidSignedAndEnvelopedData = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7, 4}
- oidDigestedData = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7, 5}
- oidEncryptedData = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7, 6}
- oidAttributeContentType = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 3}
- oidAttributeMessageDigest = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 4}
- oidAttributeSigningTime = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 5}
-)
-
-type signedData struct {
- Version int `asn1:"default:1"`
- DigestAlgorithmIdentifiers []pkix.AlgorithmIdentifier `asn1:"set"`
- ContentInfo contentInfo
- Certificates rawCertificates `asn1:"optional,tag:0"`
- CRLs []pkix.CertificateList `asn1:"optional,tag:1"`
- SignerInfos []signerInfo `asn1:"set"`
-}
-
-type rawCertificates struct {
- Raw asn1.RawContent
-}
-
-type envelopedData struct {
- Version int
- RecipientInfos []recipientInfo `asn1:"set"`
- EncryptedContentInfo encryptedContentInfo
-}
-
-type recipientInfo struct {
- Version int
- IssuerAndSerialNumber issuerAndSerial
- KeyEncryptionAlgorithm pkix.AlgorithmIdentifier
- EncryptedKey []byte
-}
-
-type encryptedContentInfo struct {
- ContentType asn1.ObjectIdentifier
- ContentEncryptionAlgorithm pkix.AlgorithmIdentifier
- EncryptedContent asn1.RawValue `asn1:"tag:0,optional"`
-}
-
-type attribute struct {
- Type asn1.ObjectIdentifier
- Value asn1.RawValue `asn1:"set"`
-}
-
-type issuerAndSerial struct {
- IssuerName asn1.RawValue
- SerialNumber *big.Int
-}
-
-// MessageDigestMismatchError is returned when the signer data digest does not
-// match the computed digest for the contained content
-type MessageDigestMismatchError struct {
- ExpectedDigest []byte
- ActualDigest []byte
-}
-
-func (err *MessageDigestMismatchError) Error() string {
- return fmt.Sprintf("pkcs7: Message digest mismatch\n\tExpected: %X\n\tActual : %X", err.ExpectedDigest, err.ActualDigest)
-}
-
-type signerInfo struct {
- Version int `asn1:"default:1"`
- IssuerAndSerialNumber issuerAndSerial
- DigestAlgorithm pkix.AlgorithmIdentifier
- AuthenticatedAttributes []attribute `asn1:"optional,tag:0"`
- DigestEncryptionAlgorithm pkix.AlgorithmIdentifier
- EncryptedDigest []byte
- UnauthenticatedAttributes []attribute `asn1:"optional,tag:1"`
-}
-
-// Parse decodes a DER encoded PKCS7 package
-func Parse(data []byte) (p7 *PKCS7, err error) {
- if len(data) == 0 {
- return nil, errors.New("pkcs7: input data is empty")
- }
- var info contentInfo
- der, err := ber2der(data)
- if err != nil {
- return nil, err
- }
- rest, err := asn1.Unmarshal(der, &info)
- if len(rest) > 0 {
- err = asn1.SyntaxError{Msg: "trailing data"}
- return
- }
- if err != nil {
- return
- }
-
- // fmt.Printf("--> Content Type: %s", info.ContentType)
- switch {
- case info.ContentType.Equal(oidSignedData):
- return parseSignedData(info.Content.Bytes)
- case info.ContentType.Equal(oidEnvelopedData):
- return parseEnvelopedData(info.Content.Bytes)
- }
- return nil, ErrUnsupportedContentType
-}
-
-func parseSignedData(data []byte) (*PKCS7, error) {
- var sd signedData
- asn1.Unmarshal(data, &sd)
- certs, err := sd.Certificates.Parse()
- if err != nil {
- return nil, err
- }
- // fmt.Printf("--> Signed Data Version %d\n", sd.Version)
-
- var compound asn1.RawValue
- var content unsignedData
-
- // The Content.Bytes maybe empty on PKI responses.
- if len(sd.ContentInfo.Content.Bytes) > 0 {
- if _, err := asn1.Unmarshal(sd.ContentInfo.Content.Bytes, &compound); err != nil {
- return nil, err
- }
- }
- // Compound octet string
- if compound.IsCompound {
- if _, err = asn1.Unmarshal(compound.Bytes, &content); err != nil {
- return nil, err
- }
- } else {
- // assuming this is tag 04
- content = compound.Bytes
- }
- return &PKCS7{
- Content: content,
- Certificates: certs,
- CRLs: sd.CRLs,
- Signers: sd.SignerInfos,
- raw: sd}, nil
-}
-
-func (raw rawCertificates) Parse() ([]*x509.Certificate, error) {
- if len(raw.Raw) == 0 {
- return nil, nil
- }
-
- var val asn1.RawValue
- if _, err := asn1.Unmarshal(raw.Raw, &val); err != nil {
- return nil, err
- }
-
- return x509.ParseCertificates(val.Bytes)
-}
-
-func parseEnvelopedData(data []byte) (*PKCS7, error) {
- var ed envelopedData
- if _, err := asn1.Unmarshal(data, &ed); err != nil {
- return nil, err
- }
- return &PKCS7{
- raw: ed,
- }, nil
-}
-
-// Verify checks the signatures of a PKCS7 object
-// WARNING: Verify does not check signing time or verify certificate chains at
-// this time.
-func (p7 *PKCS7) Verify() (err error) {
- if len(p7.Signers) == 0 {
- return errors.New("pkcs7: Message has no signers")
- }
- for _, signer := range p7.Signers {
- if err := verifySignature(p7, signer); err != nil {
- return err
- }
- }
- return nil
-}
-
-func verifySignature(p7 *PKCS7, signer signerInfo) error {
- signedData := p7.Content
- hash, err := getHashForOID(signer.DigestAlgorithm.Algorithm)
- if err != nil {
- return err
- }
- if len(signer.AuthenticatedAttributes) > 0 {
- // TODO(fullsailor): First check the content type match
- var digest []byte
- err := unmarshalAttribute(signer.AuthenticatedAttributes, oidAttributeMessageDigest, &digest)
- if err != nil {
- return err
- }
- h := hash.New()
- h.Write(p7.Content)
- computed := h.Sum(nil)
- if !hmac.Equal(digest, computed) {
- return &MessageDigestMismatchError{
- ExpectedDigest: digest,
- ActualDigest: computed,
- }
- }
- // TODO(fullsailor): Optionally verify certificate chain
- // TODO(fullsailor): Optionally verify signingTime against certificate NotAfter/NotBefore
- signedData, err = marshalAttributes(signer.AuthenticatedAttributes)
- if err != nil {
- return err
- }
- }
- cert := getCertFromCertsByIssuerAndSerial(p7.Certificates, signer.IssuerAndSerialNumber)
- if cert == nil {
- return errors.New("pkcs7: No certificate for signer")
- }
-
- algo := getSignatureAlgorithmFromAI(signer.DigestEncryptionAlgorithm)
- if algo == x509.UnknownSignatureAlgorithm {
- // I'm not sure what the spec here is, and the openssl sources were not
- // helpful. But, this is what App Store receipts appear to do.
- // The DigestEncryptionAlgorithm is just "rsaEncryption (PKCS #1)"
- // But we're expecting a digest + encryption algorithm. So... we're going
- // to determine an algorithm based on the DigestAlgorithm and this
- // encryption algorithm.
- if signer.DigestEncryptionAlgorithm.Algorithm.Equal(oidEncryptionAlgorithmRSA) {
- algo = getRSASignatureAlgorithmForDigestAlgorithm(hash)
- }
- }
- return cert.CheckSignature(algo, signedData, signer.EncryptedDigest)
-}
-
-func marshalAttributes(attrs []attribute) ([]byte, error) {
- encodedAttributes, err := asn1.Marshal(struct {
- A []attribute `asn1:"set"`
- }{A: attrs})
- if err != nil {
- return nil, err
- }
-
- // Remove the leading sequence octets
- var raw asn1.RawValue
- asn1.Unmarshal(encodedAttributes, &raw)
- return raw.Bytes, nil
-}
-
-var (
- oidDigestAlgorithmSHA1 = asn1.ObjectIdentifier{1, 3, 14, 3, 2, 26}
- oidEncryptionAlgorithmRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}
-)
-
-func getCertFromCertsByIssuerAndSerial(certs []*x509.Certificate, ias issuerAndSerial) *x509.Certificate {
- for _, cert := range certs {
- if isCertMatchForIssuerAndSerial(cert, ias) {
- return cert
- }
- }
- return nil
-}
-
-func getHashForOID(oid asn1.ObjectIdentifier) (crypto.Hash, error) {
- switch {
- case oid.Equal(oidDigestAlgorithmSHA1):
- return crypto.SHA1, nil
- case oid.Equal(oidSHA256):
- return crypto.SHA256, nil
- }
- return crypto.Hash(0), ErrUnsupportedAlgorithm
-}
-
-func getRSASignatureAlgorithmForDigestAlgorithm(hash crypto.Hash) x509.SignatureAlgorithm {
- for _, details := range signatureAlgorithmDetails {
- if details.pubKeyAlgo == x509.RSA && details.hash == hash {
- return details.algo
- }
- }
- return x509.UnknownSignatureAlgorithm
-}
-
-// GetOnlySigner returns an x509.Certificate for the first signer of the signed
-// data payload. If there are more or less than one signer, nil is returned
-func (p7 *PKCS7) GetOnlySigner() *x509.Certificate {
- if len(p7.Signers) != 1 {
- return nil
- }
- signer := p7.Signers[0]
- return getCertFromCertsByIssuerAndSerial(p7.Certificates, signer.IssuerAndSerialNumber)
-}
-
-// ErrUnsupportedAlgorithm tells you when our quick dev assumptions have failed
-var ErrUnsupportedAlgorithm = errors.New("pkcs7: cannot decrypt data: only RSA, DES, DES-EDE3, AES-256-CBC and AES-128-GCM supported")
-
-// ErrNotEncryptedContent is returned when attempting to Decrypt data that is not encrypted data
-var ErrNotEncryptedContent = errors.New("pkcs7: content data is a decryptable data type")
-
-// Decrypt decrypts encrypted content info for recipient cert and private key
-func (p7 *PKCS7) Decrypt(cert *x509.Certificate, pk crypto.PrivateKey) ([]byte, error) {
- data, ok := p7.raw.(envelopedData)
- if !ok {
- return nil, ErrNotEncryptedContent
- }
- recipient := selectRecipientForCertificate(data.RecipientInfos, cert)
- if recipient.EncryptedKey == nil {
- return nil, errors.New("pkcs7: no enveloped recipient for provided certificate")
- }
- if priv := pk.(*rsa.PrivateKey); priv != nil {
- var contentKey []byte
- contentKey, err := rsa.DecryptPKCS1v15(rand.Reader, priv, recipient.EncryptedKey)
- if err != nil {
- return nil, err
- }
- return data.EncryptedContentInfo.decrypt(contentKey)
- }
- fmt.Printf("Unsupported Private Key: %v\n", pk)
- return nil, ErrUnsupportedAlgorithm
-}
-
-var oidEncryptionAlgorithmDESCBC = asn1.ObjectIdentifier{1, 3, 14, 3, 2, 7}
-var oidEncryptionAlgorithmDESEDE3CBC = asn1.ObjectIdentifier{1, 2, 840, 113549, 3, 7}
-var oidEncryptionAlgorithmAES256CBC = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 1, 42}
-var oidEncryptionAlgorithmAES128GCM = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 1, 6}
-var oidEncryptionAlgorithmAES128CBC = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 1, 2}
-
-func (eci encryptedContentInfo) decrypt(key []byte) ([]byte, error) {
- alg := eci.ContentEncryptionAlgorithm.Algorithm
- if !alg.Equal(oidEncryptionAlgorithmDESCBC) &&
- !alg.Equal(oidEncryptionAlgorithmDESEDE3CBC) &&
- !alg.Equal(oidEncryptionAlgorithmAES256CBC) &&
- !alg.Equal(oidEncryptionAlgorithmAES128CBC) &&
- !alg.Equal(oidEncryptionAlgorithmAES128GCM) {
- fmt.Printf("Unsupported Content Encryption Algorithm: %s\n", alg)
- return nil, ErrUnsupportedAlgorithm
- }
-
- // EncryptedContent can either be constructed of multple OCTET STRINGs
- // or _be_ a tagged OCTET STRING
- var cyphertext []byte
- if eci.EncryptedContent.IsCompound {
- // Complex case to concat all of the children OCTET STRINGs
- var buf bytes.Buffer
- cypherbytes := eci.EncryptedContent.Bytes
- for {
- var part []byte
- cypherbytes, _ = asn1.Unmarshal(cypherbytes, &part)
- buf.Write(part)
- if cypherbytes == nil {
- break
- }
- }
- cyphertext = buf.Bytes()
- } else {
- // Simple case, the bytes _are_ the cyphertext
- cyphertext = eci.EncryptedContent.Bytes
- }
-
- var block cipher.Block
- var err error
-
- switch {
- case alg.Equal(oidEncryptionAlgorithmDESCBC):
- block, err = des.NewCipher(key)
- case alg.Equal(oidEncryptionAlgorithmDESEDE3CBC):
- block, err = des.NewTripleDESCipher(key)
- case alg.Equal(oidEncryptionAlgorithmAES256CBC):
- fallthrough
- case alg.Equal(oidEncryptionAlgorithmAES128GCM), alg.Equal(oidEncryptionAlgorithmAES128CBC):
- block, err = aes.NewCipher(key)
- }
-
- if err != nil {
- return nil, err
- }
-
- if alg.Equal(oidEncryptionAlgorithmAES128GCM) {
- params := aesGCMParameters{}
- paramBytes := eci.ContentEncryptionAlgorithm.Parameters.Bytes
-
- _, err := asn1.Unmarshal(paramBytes, &params)
- if err != nil {
- return nil, err
- }
-
- gcm, err := cipher.NewGCM(block)
- if err != nil {
- return nil, err
- }
-
- if len(params.Nonce) != gcm.NonceSize() {
- return nil, errors.New("pkcs7: encryption algorithm parameters are incorrect")
- }
- if params.ICVLen != gcm.Overhead() {
- return nil, errors.New("pkcs7: encryption algorithm parameters are incorrect")
- }
-
- plaintext, err := gcm.Open(nil, params.Nonce, cyphertext, nil)
- if err != nil {
- return nil, err
- }
-
- return plaintext, nil
- }
-
- iv := eci.ContentEncryptionAlgorithm.Parameters.Bytes
- if len(iv) != block.BlockSize() {
- return nil, errors.New("pkcs7: encryption algorithm parameters are malformed")
- }
- mode := cipher.NewCBCDecrypter(block, iv)
- plaintext := make([]byte, len(cyphertext))
- mode.CryptBlocks(plaintext, cyphertext)
- if plaintext, err = unpad(plaintext, mode.BlockSize()); err != nil {
- return nil, err
- }
- return plaintext, nil
-}
-
-func selectRecipientForCertificate(recipients []recipientInfo, cert *x509.Certificate) recipientInfo {
- for _, recp := range recipients {
- if isCertMatchForIssuerAndSerial(cert, recp.IssuerAndSerialNumber) {
- return recp
- }
- }
- return recipientInfo{}
-}
-
-func isCertMatchForIssuerAndSerial(cert *x509.Certificate, ias issuerAndSerial) bool {
- return cert.SerialNumber.Cmp(ias.SerialNumber) == 0 && bytes.Compare(cert.RawIssuer, ias.IssuerName.FullBytes) == 0
-}
-
-func pad(data []byte, blocklen int) ([]byte, error) {
- if blocklen < 1 {
- return nil, fmt.Errorf("invalid blocklen %d", blocklen)
- }
- padlen := blocklen - (len(data) % blocklen)
- if padlen == 0 {
- padlen = blocklen
- }
- pad := bytes.Repeat([]byte{byte(padlen)}, padlen)
- return append(data, pad...), nil
-}
-
-func unpad(data []byte, blocklen int) ([]byte, error) {
- if blocklen < 1 {
- return nil, fmt.Errorf("invalid blocklen %d", blocklen)
- }
- if len(data)%blocklen != 0 || len(data) == 0 {
- return nil, fmt.Errorf("invalid data len %d", len(data))
- }
-
- // the last byte is the length of padding
- padlen := int(data[len(data)-1])
-
- // check padding integrity, all bytes should be the same
- pad := data[len(data)-padlen:]
- for _, padbyte := range pad {
- if padbyte != byte(padlen) {
- return nil, errors.New("invalid padding")
- }
- }
-
- return data[:len(data)-padlen], nil
-}
-
-func unmarshalAttribute(attrs []attribute, attributeType asn1.ObjectIdentifier, out interface{}) error {
- for _, attr := range attrs {
- if attr.Type.Equal(attributeType) {
- _, err := asn1.Unmarshal(attr.Value.Bytes, out)
- return err
- }
- }
- return errors.New("pkcs7: attribute type not in attributes")
-}
-
-// UnmarshalSignedAttribute decodes a single attribute from the signer info
-func (p7 *PKCS7) UnmarshalSignedAttribute(attributeType asn1.ObjectIdentifier, out interface{}) error {
- sd, ok := p7.raw.(signedData)
- if !ok {
- return errors.New("pkcs7: payload is not signedData content")
- }
- if len(sd.SignerInfos) < 1 {
- return errors.New("pkcs7: payload has no signers")
- }
- attributes := sd.SignerInfos[0].AuthenticatedAttributes
- return unmarshalAttribute(attributes, attributeType, out)
-}
-
-// SignedData is an opaque data structure for creating signed data payloads
-type SignedData struct {
- sd signedData
- certs []*x509.Certificate
- messageDigest []byte
-}
-
-// Attribute represents a key value pair attribute. Value must be marshalable byte
-// `encoding/asn1`
-type Attribute struct {
- Type asn1.ObjectIdentifier
- Value interface{}
-}
-
-// SignerInfoConfig are optional values to include when adding a signer
-type SignerInfoConfig struct {
- ExtraSignedAttributes []Attribute
-}
-
-// NewSignedData initializes a SignedData with content
-func NewSignedData(data []byte) (*SignedData, error) {
- content, err := asn1.Marshal(data)
- if err != nil {
- return nil, err
- }
- ci := contentInfo{
- ContentType: oidData,
- Content: asn1.RawValue{Class: 2, Tag: 0, Bytes: content, IsCompound: true},
- }
- digAlg := pkix.AlgorithmIdentifier{
- Algorithm: oidDigestAlgorithmSHA1,
- }
- h := crypto.SHA1.New()
- h.Write(data)
- md := h.Sum(nil)
- sd := signedData{
- ContentInfo: ci,
- Version: 1,
- DigestAlgorithmIdentifiers: []pkix.AlgorithmIdentifier{digAlg},
- }
- return &SignedData{sd: sd, messageDigest: md}, nil
-}
-
-type attributes struct {
- types []asn1.ObjectIdentifier
- values []interface{}
-}
-
-// Add adds the attribute, maintaining insertion order
-func (attrs *attributes) Add(attrType asn1.ObjectIdentifier, value interface{}) {
- attrs.types = append(attrs.types, attrType)
- attrs.values = append(attrs.values, value)
-}
-
-type sortableAttribute struct {
- SortKey []byte
- Attribute attribute
-}
-
-type attributeSet []sortableAttribute
-
-func (sa attributeSet) Len() int {
- return len(sa)
-}
-
-func (sa attributeSet) Less(i, j int) bool {
- return bytes.Compare(sa[i].SortKey, sa[j].SortKey) < 0
-}
-
-func (sa attributeSet) Swap(i, j int) {
- sa[i], sa[j] = sa[j], sa[i]
-}
-
-func (sa attributeSet) Attributes() []attribute {
- attrs := make([]attribute, len(sa))
- for i, attr := range sa {
- attrs[i] = attr.Attribute
- }
- return attrs
-}
-
-func (attrs *attributes) ForMarshaling() ([]attribute, error) {
- sortables := make(attributeSet, len(attrs.types))
- for i := range sortables {
- attrType := attrs.types[i]
- attrValue := attrs.values[i]
- asn1Value, err := asn1.Marshal(attrValue)
- if err != nil {
- return nil, err
- }
- attr := attribute{
- Type: attrType,
- Value: asn1.RawValue{Tag: 17, IsCompound: true, Bytes: asn1Value}, // 17 == SET tag
- }
- encoded, err := asn1.Marshal(attr)
- if err != nil {
- return nil, err
- }
- sortables[i] = sortableAttribute{
- SortKey: encoded,
- Attribute: attr,
- }
- }
- sort.Sort(sortables)
- return sortables.Attributes(), nil
-}
-
-// AddSigner signs attributes about the content and adds certificate to payload
-func (sd *SignedData) AddSigner(cert *x509.Certificate, pkey crypto.PrivateKey, config SignerInfoConfig) error {
- attrs := &attributes{}
- attrs.Add(oidAttributeContentType, sd.sd.ContentInfo.ContentType)
- attrs.Add(oidAttributeMessageDigest, sd.messageDigest)
- attrs.Add(oidAttributeSigningTime, time.Now())
- for _, attr := range config.ExtraSignedAttributes {
- attrs.Add(attr.Type, attr.Value)
- }
- finalAttrs, err := attrs.ForMarshaling()
- if err != nil {
- return err
- }
- signature, err := signAttributes(finalAttrs, pkey, crypto.SHA1)
- if err != nil {
- return err
- }
-
- ias, err := cert2issuerAndSerial(cert)
- if err != nil {
- return err
- }
-
- signer := signerInfo{
- AuthenticatedAttributes: finalAttrs,
- DigestAlgorithm: pkix.AlgorithmIdentifier{Algorithm: oidDigestAlgorithmSHA1},
- DigestEncryptionAlgorithm: pkix.AlgorithmIdentifier{Algorithm: oidSignatureSHA1WithRSA},
- IssuerAndSerialNumber: ias,
- EncryptedDigest: signature,
- Version: 1,
- }
- // create signature of signed attributes
- sd.certs = append(sd.certs, cert)
- sd.sd.SignerInfos = append(sd.sd.SignerInfos, signer)
- return nil
-}
-
-// AddCertificate adds the certificate to the payload. Useful for parent certificates
-func (sd *SignedData) AddCertificate(cert *x509.Certificate) {
- sd.certs = append(sd.certs, cert)
-}
-
-// Detach removes content from the signed data struct to make it a detached signature.
-// This must be called right before Finish()
-func (sd *SignedData) Detach() {
- sd.sd.ContentInfo = contentInfo{ContentType: oidData}
-}
-
-// Finish marshals the content and its signers
-func (sd *SignedData) Finish() ([]byte, error) {
- sd.sd.Certificates = marshalCertificates(sd.certs)
- inner, err := asn1.Marshal(sd.sd)
- if err != nil {
- return nil, err
- }
- outer := contentInfo{
- ContentType: oidSignedData,
- Content: asn1.RawValue{Class: 2, Tag: 0, Bytes: inner, IsCompound: true},
- }
- return asn1.Marshal(outer)
-}
-
-func cert2issuerAndSerial(cert *x509.Certificate) (issuerAndSerial, error) {
- var ias issuerAndSerial
- // The issuer RDNSequence has to match exactly the sequence in the certificate
- // We cannot use cert.Issuer.ToRDNSequence() here since it mangles the sequence
- ias.IssuerName = asn1.RawValue{FullBytes: cert.RawIssuer}
- ias.SerialNumber = cert.SerialNumber
-
- return ias, nil
-}
-
-// signs the DER encoded form of the attributes with the private key
-func signAttributes(attrs []attribute, pkey crypto.PrivateKey, hash crypto.Hash) ([]byte, error) {
- attrBytes, err := marshalAttributes(attrs)
- if err != nil {
- return nil, err
- }
- h := hash.New()
- h.Write(attrBytes)
- hashed := h.Sum(nil)
- switch priv := pkey.(type) {
- case *rsa.PrivateKey:
- return rsa.SignPKCS1v15(rand.Reader, priv, crypto.SHA1, hashed)
- }
- return nil, ErrUnsupportedAlgorithm
-}
-
-// concats and wraps the certificates in the RawValue structure
-func marshalCertificates(certs []*x509.Certificate) rawCertificates {
- var buf bytes.Buffer
- for _, cert := range certs {
- buf.Write(cert.Raw)
- }
- rawCerts, _ := marshalCertificateBytes(buf.Bytes())
- return rawCerts
-}
-
-// Even though, the tag & length are stripped out during marshalling the
-// RawContent, we have to encode it into the RawContent. If its missing,
-// then `asn1.Marshal()` will strip out the certificate wrapper instead.
-func marshalCertificateBytes(certs []byte) (rawCertificates, error) {
- var val = asn1.RawValue{Bytes: certs, Class: 2, Tag: 0, IsCompound: true}
- b, err := asn1.Marshal(val)
- if err != nil {
- return rawCertificates{}, err
- }
- return rawCertificates{Raw: b}, nil
-}
-
-// DegenerateCertificate creates a signed data structure containing only the
-// provided certificate or certificate chain.
-func DegenerateCertificate(cert []byte) ([]byte, error) {
- rawCert, err := marshalCertificateBytes(cert)
- if err != nil {
- return nil, err
- }
- emptyContent := contentInfo{ContentType: oidData}
- sd := signedData{
- Version: 1,
- ContentInfo: emptyContent,
- Certificates: rawCert,
- CRLs: []pkix.CertificateList{},
- }
- content, err := asn1.Marshal(sd)
- if err != nil {
- return nil, err
- }
- signedContent := contentInfo{
- ContentType: oidSignedData,
- Content: asn1.RawValue{Class: 2, Tag: 0, Bytes: content, IsCompound: true},
- }
- return asn1.Marshal(signedContent)
-}
-
-const (
- EncryptionAlgorithmDESCBC = iota
- EncryptionAlgorithmAES128GCM
-)
-
-// ContentEncryptionAlgorithm determines the algorithm used to encrypt the
-// plaintext message. Change the value of this variable to change which
-// algorithm is used in the Encrypt() function.
-var ContentEncryptionAlgorithm = EncryptionAlgorithmDESCBC
-
-// ErrUnsupportedEncryptionAlgorithm is returned when attempting to encrypt
-// content with an unsupported algorithm.
-var ErrUnsupportedEncryptionAlgorithm = errors.New("pkcs7: cannot encrypt content: only DES-CBC and AES-128-GCM supported")
-
-const nonceSize = 12
-
-type aesGCMParameters struct {
- Nonce []byte `asn1:"tag:4"`
- ICVLen int
-}
-
-func encryptAES128GCM(content []byte) ([]byte, *encryptedContentInfo, error) {
- // Create AES key and nonce
- key := make([]byte, 16)
- nonce := make([]byte, nonceSize)
-
- _, err := rand.Read(key)
- if err != nil {
- return nil, nil, err
- }
-
- _, err = rand.Read(nonce)
- if err != nil {
- return nil, nil, err
- }
-
- // Encrypt content
- block, err := aes.NewCipher(key)
- if err != nil {
- return nil, nil, err
- }
-
- gcm, err := cipher.NewGCM(block)
- if err != nil {
- return nil, nil, err
- }
-
- ciphertext := gcm.Seal(nil, nonce, content, nil)
-
- // Prepare ASN.1 Encrypted Content Info
- paramSeq := aesGCMParameters{
- Nonce: nonce,
- ICVLen: gcm.Overhead(),
- }
-
- paramBytes, err := asn1.Marshal(paramSeq)
- if err != nil {
- return nil, nil, err
- }
-
- eci := encryptedContentInfo{
- ContentType: oidData,
- ContentEncryptionAlgorithm: pkix.AlgorithmIdentifier{
- Algorithm: oidEncryptionAlgorithmAES128GCM,
- Parameters: asn1.RawValue{
- Tag: asn1.TagSequence,
- Bytes: paramBytes,
- },
- },
- EncryptedContent: marshalEncryptedContent(ciphertext),
- }
-
- return key, &eci, nil
-}
-
-func encryptDESCBC(content []byte) ([]byte, *encryptedContentInfo, error) {
- // Create DES key & CBC IV
- key := make([]byte, 8)
- iv := make([]byte, des.BlockSize)
- _, err := rand.Read(key)
- if err != nil {
- return nil, nil, err
- }
- _, err = rand.Read(iv)
- if err != nil {
- return nil, nil, err
- }
-
- // Encrypt padded content
- block, err := des.NewCipher(key)
- if err != nil {
- return nil, nil, err
- }
- mode := cipher.NewCBCEncrypter(block, iv)
- plaintext, err := pad(content, mode.BlockSize())
- cyphertext := make([]byte, len(plaintext))
- mode.CryptBlocks(cyphertext, plaintext)
-
- // Prepare ASN.1 Encrypted Content Info
- eci := encryptedContentInfo{
- ContentType: oidData,
- ContentEncryptionAlgorithm: pkix.AlgorithmIdentifier{
- Algorithm: oidEncryptionAlgorithmDESCBC,
- Parameters: asn1.RawValue{Tag: 4, Bytes: iv},
- },
- EncryptedContent: marshalEncryptedContent(cyphertext),
- }
-
- return key, &eci, nil
-}
-
-// Encrypt creates and returns an envelope data PKCS7 structure with encrypted
-// recipient keys for each recipient public key.
-//
-// The algorithm used to perform encryption is determined by the current value
-// of the global ContentEncryptionAlgorithm package variable. By default, the
-// value is EncryptionAlgorithmDESCBC. To use a different algorithm, change the
-// value before calling Encrypt(). For example:
-//
-// ContentEncryptionAlgorithm = EncryptionAlgorithmAES128GCM
-//
-// TODO(fullsailor): Add support for encrypting content with other algorithms
-func Encrypt(content []byte, recipients []*x509.Certificate) ([]byte, error) {
- var eci *encryptedContentInfo
- var key []byte
- var err error
-
- // Apply chosen symmetric encryption method
- switch ContentEncryptionAlgorithm {
- case EncryptionAlgorithmDESCBC:
- key, eci, err = encryptDESCBC(content)
-
- case EncryptionAlgorithmAES128GCM:
- key, eci, err = encryptAES128GCM(content)
-
- default:
- return nil, ErrUnsupportedEncryptionAlgorithm
- }
-
- if err != nil {
- return nil, err
- }
-
- // Prepare each recipient's encrypted cipher key
- recipientInfos := make([]recipientInfo, len(recipients))
- for i, recipient := range recipients {
- encrypted, err := encryptKey(key, recipient)
- if err != nil {
- return nil, err
- }
- ias, err := cert2issuerAndSerial(recipient)
- if err != nil {
- return nil, err
- }
- info := recipientInfo{
- Version: 0,
- IssuerAndSerialNumber: ias,
- KeyEncryptionAlgorithm: pkix.AlgorithmIdentifier{
- Algorithm: oidEncryptionAlgorithmRSA,
- },
- EncryptedKey: encrypted,
- }
- recipientInfos[i] = info
- }
-
- // Prepare envelope content
- envelope := envelopedData{
- EncryptedContentInfo: *eci,
- Version: 0,
- RecipientInfos: recipientInfos,
- }
- innerContent, err := asn1.Marshal(envelope)
- if err != nil {
- return nil, err
- }
-
- // Prepare outer payload structure
- wrapper := contentInfo{
- ContentType: oidEnvelopedData,
- Content: asn1.RawValue{Class: 2, Tag: 0, IsCompound: true, Bytes: innerContent},
- }
-
- return asn1.Marshal(wrapper)
-}
-
-func marshalEncryptedContent(content []byte) asn1.RawValue {
- asn1Content, _ := asn1.Marshal(content)
- return asn1.RawValue{Tag: 0, Class: 2, Bytes: asn1Content, IsCompound: true}
-}
-
-func encryptKey(key []byte, recipient *x509.Certificate) ([]byte, error) {
- if pub := recipient.PublicKey.(*rsa.PublicKey); pub != nil {
- return rsa.EncryptPKCS1v15(rand.Reader, pub, key)
- }
- return nil, ErrUnsupportedAlgorithm
-}
diff --git a/vendor/github.com/fullsailor/pkcs7/x509.go b/vendor/github.com/fullsailor/pkcs7/x509.go
deleted file mode 100644
index 195fd0e4b..000000000
--- a/vendor/github.com/fullsailor/pkcs7/x509.go
+++ /dev/null
@@ -1,133 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the go/golang LICENSE file.
-
-package pkcs7
-
-// These are private constants and functions from the crypto/x509 package that
-// are useful when dealing with signatures verified by x509 certificates
-
-import (
- "bytes"
- "crypto"
- "crypto/x509"
- "crypto/x509/pkix"
- "encoding/asn1"
-)
-
-var (
- oidSignatureMD2WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 2}
- oidSignatureMD5WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 4}
- oidSignatureSHA1WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}
- oidSignatureSHA256WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 11}
- oidSignatureSHA384WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 12}
- oidSignatureSHA512WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 13}
- oidSignatureRSAPSS = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 10}
- oidSignatureDSAWithSHA1 = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 3}
- oidSignatureDSAWithSHA256 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 3, 2}
- oidSignatureECDSAWithSHA1 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 1}
- oidSignatureECDSAWithSHA256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 2}
- oidSignatureECDSAWithSHA384 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 3}
- oidSignatureECDSAWithSHA512 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 4}
-
- oidSHA256 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 1}
- oidSHA384 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 2}
- oidSHA512 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 3}
-
- oidMGF1 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 8}
-
- // oidISOSignatureSHA1WithRSA means the same as oidSignatureSHA1WithRSA
- // but it's specified by ISO. Microsoft's makecert.exe has been known
- // to produce certificates with this OID.
- oidISOSignatureSHA1WithRSA = asn1.ObjectIdentifier{1, 3, 14, 3, 2, 29}
-)
-
-var signatureAlgorithmDetails = []struct {
- algo x509.SignatureAlgorithm
- name string
- oid asn1.ObjectIdentifier
- pubKeyAlgo x509.PublicKeyAlgorithm
- hash crypto.Hash
-}{
- {x509.MD2WithRSA, "MD2-RSA", oidSignatureMD2WithRSA, x509.RSA, crypto.Hash(0) /* no value for MD2 */},
- {x509.MD5WithRSA, "MD5-RSA", oidSignatureMD5WithRSA, x509.RSA, crypto.MD5},
- {x509.SHA1WithRSA, "SHA1-RSA", oidSignatureSHA1WithRSA, x509.RSA, crypto.SHA1},
- {x509.SHA1WithRSA, "SHA1-RSA", oidISOSignatureSHA1WithRSA, x509.RSA, crypto.SHA1},
- {x509.SHA256WithRSA, "SHA256-RSA", oidSignatureSHA256WithRSA, x509.RSA, crypto.SHA256},
- {x509.SHA384WithRSA, "SHA384-RSA", oidSignatureSHA384WithRSA, x509.RSA, crypto.SHA384},
- {x509.SHA512WithRSA, "SHA512-RSA", oidSignatureSHA512WithRSA, x509.RSA, crypto.SHA512},
- {x509.SHA256WithRSAPSS, "SHA256-RSAPSS", oidSignatureRSAPSS, x509.RSA, crypto.SHA256},
- {x509.SHA384WithRSAPSS, "SHA384-RSAPSS", oidSignatureRSAPSS, x509.RSA, crypto.SHA384},
- {x509.SHA512WithRSAPSS, "SHA512-RSAPSS", oidSignatureRSAPSS, x509.RSA, crypto.SHA512},
- {x509.DSAWithSHA1, "DSA-SHA1", oidSignatureDSAWithSHA1, x509.DSA, crypto.SHA1},
- {x509.DSAWithSHA256, "DSA-SHA256", oidSignatureDSAWithSHA256, x509.DSA, crypto.SHA256},
- {x509.ECDSAWithSHA1, "ECDSA-SHA1", oidSignatureECDSAWithSHA1, x509.ECDSA, crypto.SHA1},
- {x509.ECDSAWithSHA256, "ECDSA-SHA256", oidSignatureECDSAWithSHA256, x509.ECDSA, crypto.SHA256},
- {x509.ECDSAWithSHA384, "ECDSA-SHA384", oidSignatureECDSAWithSHA384, x509.ECDSA, crypto.SHA384},
- {x509.ECDSAWithSHA512, "ECDSA-SHA512", oidSignatureECDSAWithSHA512, x509.ECDSA, crypto.SHA512},
-}
-
-// pssParameters reflects the parameters in an AlgorithmIdentifier that
-// specifies RSA PSS. See https://tools.ietf.org/html/rfc3447#appendix-A.2.3
-type pssParameters struct {
- // The following three fields are not marked as
- // optional because the default values specify SHA-1,
- // which is no longer suitable for use in signatures.
- Hash pkix.AlgorithmIdentifier `asn1:"explicit,tag:0"`
- MGF pkix.AlgorithmIdentifier `asn1:"explicit,tag:1"`
- SaltLength int `asn1:"explicit,tag:2"`
- TrailerField int `asn1:"optional,explicit,tag:3,default:1"`
-}
-
-// asn1.NullBytes is not available prior to Go 1.9
-var nullBytes = []byte{5, 0}
-
-func getSignatureAlgorithmFromAI(ai pkix.AlgorithmIdentifier) x509.SignatureAlgorithm {
- if !ai.Algorithm.Equal(oidSignatureRSAPSS) {
- for _, details := range signatureAlgorithmDetails {
- if ai.Algorithm.Equal(details.oid) {
- return details.algo
- }
- }
- return x509.UnknownSignatureAlgorithm
- }
-
- // RSA PSS is special because it encodes important parameters
- // in the Parameters.
-
- var params pssParameters
- if _, err := asn1.Unmarshal(ai.Parameters.FullBytes, &params); err != nil {
- return x509.UnknownSignatureAlgorithm
- }
-
- var mgf1HashFunc pkix.AlgorithmIdentifier
- if _, err := asn1.Unmarshal(params.MGF.Parameters.FullBytes, &mgf1HashFunc); err != nil {
- return x509.UnknownSignatureAlgorithm
- }
-
- // PSS is greatly overburdened with options. This code forces
- // them into three buckets by requiring that the MGF1 hash
- // function always match the message hash function (as
- // recommended in
- // https://tools.ietf.org/html/rfc3447#section-8.1), that the
- // salt length matches the hash length, and that the trailer
- // field has the default value.
- if !bytes.Equal(params.Hash.Parameters.FullBytes, nullBytes) ||
- !params.MGF.Algorithm.Equal(oidMGF1) ||
- !mgf1HashFunc.Algorithm.Equal(params.Hash.Algorithm) ||
- !bytes.Equal(mgf1HashFunc.Parameters.FullBytes, nullBytes) ||
- params.TrailerField != 1 {
- return x509.UnknownSignatureAlgorithm
- }
-
- switch {
- case params.Hash.Algorithm.Equal(oidSHA256) && params.SaltLength == 32:
- return x509.SHA256WithRSAPSS
- case params.Hash.Algorithm.Equal(oidSHA384) && params.SaltLength == 48:
- return x509.SHA384WithRSAPSS
- case params.Hash.Algorithm.Equal(oidSHA512) && params.SaltLength == 64:
- return x509.SHA512WithRSAPSS
- }
-
- return x509.UnknownSignatureAlgorithm
-}