From 37f70dc813a1a5e8c42a23324a13253b1e2be6b0 Mon Sep 17 00:00:00 2001 From: Yannic Bonenberger Date: Fri, 23 Dec 2016 18:31:19 +0100 Subject: [PATCH 1/6] Support for intermediate certificates --- pkcs7/common.go | 39 ++++++++------- pkcs7/sign.go | 127 +++++++++++++++++++++++++++++++++++++----------- 2 files changed, 119 insertions(+), 47 deletions(-) diff --git a/pkcs7/common.go b/pkcs7/common.go index 546d8e5..588d7b5 100644 --- a/pkcs7/common.go +++ b/pkcs7/common.go @@ -25,57 +25,60 @@ var ( oidPKCS1RSAEncryption = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1} ) -type AlgorithmIdentifier struct { +type algorithmIdentifier struct { Algorithm asn1.ObjectIdentifier Parameters asn1.RawValue } -type IssuerAndSerialNumber struct { +type issuerAndSerialNumber struct { Issuer asn1.RawValue SerialNumber *big.Int } -type SignerInfo struct { +type signerInfo struct { Version int - SignedIdentifier IssuerAndSerialNumber - DigestAlgorithm AlgorithmIdentifier - AuthenticatedAttributes Attributes `asn1:"tag:0"` - DigestEncryptionAlgorithm AlgorithmIdentifier + SignedIdentifier issuerAndSerialNumber + DigestAlgorithm algorithmIdentifier + AuthenticatedAttributes []attribute `asn1:"tag:0"` + DigestEncryptionAlgorithm algorithmIdentifier EncryptedDigest []byte UnauthenticatedAttributes int `asn1:"optional"` } -type ContentInfo struct { +type contentInfo struct { ContentType asn1.ObjectIdentifier Content asn1.RawValue `asn1:"optional"` } -type SignedData struct { +type signedData struct { Version int - DigestAlgorithms []AlgorithmIdentifier `asn1:"set"` - ContentInfo ContentInfo + DigestAlgorithms []algorithmIdentifier `asn1:"set"` + ContentInfo contentInfo Certificates asn1.RawValue `asn1:"optional"` Crls asn1.RawValue `asn1:"optional"` - SignerInfos []SignerInfo `asn1:"set"` + SignerInfos []signerInfo `asn1:"set"` } -type SignedDataWrapper struct { +type signedDataWrapper struct { Oid asn1.ObjectIdentifier SignedData asn1.RawValue } // -type Attribute struct { +type attribute struct { Type asn1.ObjectIdentifier Values []interface{} `asn1:"set"` } -type Attributes []Attribute - -func NewAttribute(typ asn1.ObjectIdentifier, val interface{}) Attribute { +func newAttribute(typ asn1.ObjectIdentifier, val interface{}) attribute { if t, ok := val.(time.Time); ok { val = asn1.RawValue{Tag: 23, Bytes: []byte(t.Format("060102150405Z"))} } - return Attribute{Type: typ, Values: []interface{}{val}} + return attribute{ + Type: typ, + Values: []interface{}{ + val, + }, + } } diff --git a/pkcs7/sign.go b/pkcs7/sign.go index e406193..a06353c 100644 --- a/pkcs7/sign.go +++ b/pkcs7/sign.go @@ -11,40 +11,91 @@ import ( "crypto/sha256" "crypto/x509" "encoding/asn1" + "errors" "io" "time" ) -func Sign(r io.Reader, cert *x509.Certificate, priv *rsa.PrivateKey) ([]byte, error) { - hash := sha256.New() - if _, err := io.Copy(hash, r); err != nil { +// Create Signature of message +// message must be of type io.Reader or []byte +// Returns signature and any error encountered. +func Sign(message interface{}, certificate *x509.Certificate, privateKey *rsa.PrivateKey) ([]byte, error) { + return SignIntermediate(message, certificate, privateKey, nil) +} + +// Create Signature of message including intermediate certificates. +// message must be of type io.Reader or []byte +// Returns signature and any error encountered. +func SignIntermediate(message interface{}, certificate *x509.Certificate, privateKey *rsa.PrivateKey, intermediateCertificates []*x509.Certificate) ([]byte, error) { + // Check if parameters are valid + if certificate == nil { + return nil, errors.New("\"certificate\" cannot be nil.") + } + + if privateKey == nil { + return nil, errors.New("\"privateKey\" cannot be nil.") + } + + messageDigest, err := checksum(message) + if err != nil { return nil, err } - messageDigest := hash.Sum(nil) - signedData := SignedData{ + // Copy intermediateCertificates to certificate stack + raw := certificate.Raw + if intermediateCertificates != nil { + for _, intermediate := range intermediateCertificates { + if intermediate != nil { + raw = append(raw, intermediate.Raw...) + } + } + } + + signedData := signedData{ Version: 1, - DigestAlgorithms: []AlgorithmIdentifier{ - AlgorithmIdentifier{Algorithm: oidSHA256, Parameters: asn1.RawValue{Tag: 5}}, + DigestAlgorithms: []algorithmIdentifier{ + { + Algorithm: oidSHA256, + Parameters: asn1.RawValue{ + Tag: 5, + }, + }, }, - ContentInfo: ContentInfo{ + ContentInfo: contentInfo{ ContentType: oidPKCS7Data, }, - Certificates: asn1.RawValue{Class: 2, Tag: 0, Bytes: cert.Raw, IsCompound: true}, - SignerInfos: []SignerInfo{ - SignerInfo{ + Certificates: asn1.RawValue{ + Class: 2, + Tag: 0, + Bytes: raw, + IsCompound: true, + }, + SignerInfos: []signerInfo{ + { Version: 1, - SignedIdentifier: IssuerAndSerialNumber{ - Issuer: asn1.RawValue{FullBytes: cert.RawIssuer}, - SerialNumber: cert.SerialNumber, + SignedIdentifier: issuerAndSerialNumber{ + Issuer: asn1.RawValue{ + FullBytes: certificate.RawIssuer, + }, + SerialNumber: certificate.SerialNumber, + }, + DigestAlgorithm: algorithmIdentifier{ + Algorithm: oidSHA256, + Parameters: asn1.RawValue{ + Tag: 5, + }, }, - DigestAlgorithm: AlgorithmIdentifier{Algorithm: oidSHA256, Parameters: asn1.RawValue{Tag: 5}}, - AuthenticatedAttributes: Attributes{ - NewAttribute(oidPKCS9ContentType, oidPKCS7Data), - NewAttribute(oidPKCS9SigningTime, time.Now().UTC()), - NewAttribute(oidPKCS9MessageDigest, messageDigest), + AuthenticatedAttributes: []attribute{ + newAttribute(oidPKCS9ContentType, oidPKCS7Data), + newAttribute(oidPKCS9SigningTime, time.Now().UTC()), + newAttribute(oidPKCS9MessageDigest, messageDigest), + }, + DigestEncryptionAlgorithm: algorithmIdentifier{ + Algorithm: oidPKCS1RSAEncryption, + Parameters: asn1.RawValue{ + Tag: 5, + }, }, - DigestEncryptionAlgorithm: AlgorithmIdentifier{Algorithm: oidPKCS1RSAEncryption, Parameters: asn1.RawValue{Tag: 5}}, EncryptedDigest: nil, // We fill this in later UnauthenticatedAttributes: 0, }, @@ -56,20 +107,17 @@ func Sign(r io.Reader, cert *x509.Certificate, priv *rsa.PrivateKey) ([]byte, er return nil, err } - // For the digest of the authenticated attributes, we need a - // slightly different encoding. Change the attributes from a - // SEQUENCE to a SET. - originalFirstByte := encodedAuthenticatedAttributes[0] encodedAuthenticatedAttributes[0] = 0x31 - hash = sha256.New() - hash.Write(encodedAuthenticatedAttributes) - attributesDigest := hash.Sum(nil) + attributesDigest, err := checksum(encodedAuthenticatedAttributes) + if err != nil { + return nil, err + } encodedAuthenticatedAttributes[0] = originalFirstByte - encryptedDigest, err := rsa.SignPKCS1v15(rand.Reader, priv, crypto.SHA256, attributesDigest) + encryptedDigest, err := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, attributesDigest) if err != nil { return nil, err } @@ -80,10 +128,31 @@ func Sign(r io.Reader, cert *x509.Certificate, priv *rsa.PrivateKey) ([]byte, er return nil, err } - signedDataWrapper := SignedDataWrapper{ + signedDataWrapper := signedDataWrapper{ Oid: oidPKCS7SignedData, SignedData: asn1.RawValue{Class: 2, Tag: 0, Bytes: encodedSignedData, IsCompound: true}, } return asn1.Marshal(signedDataWrapper) } + +// Create sha256 checksum of message +// message must be of type io.Reader or []byte +// Returns checksum and any error encountered. +func checksum(message interface{}) ([]byte, error) { + hash := sha256.New() + + if msg, ok := message.(io.Reader); ok { + if _, err := io.Copy(hash, msg); err != nil { + return nil, err + } + return hash.Sum(nil), nil + } + + if msg, ok := message.([]byte); ok { + hash.Write(msg) + return hash.Sum(nil), nil + } + + return nil, errors.New("\"message\" must be of type io.Reader or []byte") +} From fe174a2d0a7c98f791e3a23845c3c22a1a33fa0d Mon Sep 17 00:00:00 2001 From: Yannic Bonenberger Date: Sun, 8 Jan 2017 15:06:21 +0100 Subject: [PATCH 2/6] Remove unnecessary nil --- pkcs7/sign.go | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/pkcs7/sign.go b/pkcs7/sign.go index a06353c..122c3c6 100644 --- a/pkcs7/sign.go +++ b/pkcs7/sign.go @@ -43,11 +43,9 @@ func SignIntermediate(message interface{}, certificate *x509.Certificate, privat // Copy intermediateCertificates to certificate stack raw := certificate.Raw - if intermediateCertificates != nil { - for _, intermediate := range intermediateCertificates { - if intermediate != nil { - raw = append(raw, intermediate.Raw...) - } + for _, intermediate := range intermediateCertificates { + if intermediate != nil { + raw = append(raw, intermediate.Raw...) } } From 77cdc19b8129d4f803a98e7e7503d4d90cd51c16 Mon Sep 17 00:00:00 2001 From: Yannic Bonenberger Date: Sun, 8 Jan 2017 15:43:09 +0100 Subject: [PATCH 3/6] Add interface Hashable --- pkcs7/hashable.go | 42 +++++++++++++++++++++++++++++++++++++ pkcs7/sign.go | 53 ++++++++++++++++++++--------------------------- 2 files changed, 64 insertions(+), 31 deletions(-) create mode 100644 pkcs7/hashable.go diff --git a/pkcs7/hashable.go b/pkcs7/hashable.go new file mode 100644 index 0000000..76243ac --- /dev/null +++ b/pkcs7/hashable.go @@ -0,0 +1,42 @@ +package pkcs7 + +import ( + "crypto/sha256" + "io" +) + +type Hashable interface { + Hash() ([]byte, error) +} + +type hashableReader struct { + r io.Reader +} + +func (h *hashableReader) Hash() ([]byte, error) { + hash := sha256.New() + + if _, err := io.Copy(hash, h.r); err != nil { + return nil, err + } + + return hash.Sum(nil), nil +} + +func NewHashableReader(r io.Reader) Hashable { + return &hashableReader{r: r} +} + +type hashableBytes struct { + b []byte +} + +func (h *hashableBytes) Hash() ([]byte, error) { + hash := sha256.New() + hash.Write(h.b) + return hash.Sum(nil), nil +} + +func NewHashableBytes(b []byte) Hashable { + return &hashableBytes{b: b} +} diff --git a/pkcs7/sign.go b/pkcs7/sign.go index 122c3c6..64960a6 100644 --- a/pkcs7/sign.go +++ b/pkcs7/sign.go @@ -8,7 +8,6 @@ import ( "crypto" "crypto/rand" "crypto/rsa" - "crypto/sha256" "crypto/x509" "encoding/asn1" "errors" @@ -16,17 +15,29 @@ import ( "time" ) -// Create Signature of message -// message must be of type io.Reader or []byte +// Create signature from Reader // Returns signature and any error encountered. -func Sign(message interface{}, certificate *x509.Certificate, privateKey *rsa.PrivateKey) ([]byte, error) { - return SignIntermediate(message, certificate, privateKey, nil) +func Sign(reader io.Reader, certificate *x509.Certificate, privateKey *rsa.PrivateKey) ([]byte, error) { + hashable := NewHashableReader(reader) + return SignDataIntermediate(hashable, certificate, privateKey, nil) } -// Create Signature of message including intermediate certificates. -// message must be of type io.Reader or []byte +// Create signature from Reader including intermediate certificates. // Returns signature and any error encountered. -func SignIntermediate(message interface{}, certificate *x509.Certificate, privateKey *rsa.PrivateKey, intermediateCertificates []*x509.Certificate) ([]byte, error) { +func SignIntermediate(reader io.Reader, certificate *x509.Certificate, privateKey *rsa.PrivateKey, intermediateCertificates []*x509.Certificate) ([]byte, error) { + hashable := NewHashableReader(reader) + return SignDataIntermediate(hashable, certificate, privateKey, intermediateCertificates) +} + +// Creates signature +// Returns signature and any error encountered. +func SignData(hashable Hashable, certificate *x509.Certificate, privateKey *rsa.PrivateKey) ([]byte, error) { + return SignDataIntermediate(hashable, certificate, privateKey, nil) +} + +// Create signature including intermediate certificates. +// Returns signature and any error encountered. +func SignDataIntermediate(hashable Hashable, certificate *x509.Certificate, privateKey *rsa.PrivateKey, intermediateCertificates []*x509.Certificate) ([]byte, error) { // Check if parameters are valid if certificate == nil { return nil, errors.New("\"certificate\" cannot be nil.") @@ -36,7 +47,7 @@ func SignIntermediate(message interface{}, certificate *x509.Certificate, privat return nil, errors.New("\"privateKey\" cannot be nil.") } - messageDigest, err := checksum(message) + messageDigest, err := hashable.Hash() if err != nil { return nil, err } @@ -108,7 +119,8 @@ func SignIntermediate(message interface{}, certificate *x509.Certificate, privat originalFirstByte := encodedAuthenticatedAttributes[0] encodedAuthenticatedAttributes[0] = 0x31 - attributesDigest, err := checksum(encodedAuthenticatedAttributes) + digest := NewHashableBytes(encodedAuthenticatedAttributes) + attributesDigest, err := digest.Hash() if err != nil { return nil, err } @@ -133,24 +145,3 @@ func SignIntermediate(message interface{}, certificate *x509.Certificate, privat return asn1.Marshal(signedDataWrapper) } - -// Create sha256 checksum of message -// message must be of type io.Reader or []byte -// Returns checksum and any error encountered. -func checksum(message interface{}) ([]byte, error) { - hash := sha256.New() - - if msg, ok := message.(io.Reader); ok { - if _, err := io.Copy(hash, msg); err != nil { - return nil, err - } - return hash.Sum(nil), nil - } - - if msg, ok := message.([]byte); ok { - hash.Write(msg) - return hash.Sum(nil), nil - } - - return nil, errors.New("\"message\" must be of type io.Reader or []byte") -} From 11803ea2d749e062f2389d422bf9d7df1f9d9cbd Mon Sep 17 00:00:00 2001 From: Yannic Bonenberger Date: Sun, 8 Jan 2017 17:41:33 +0100 Subject: [PATCH 4/6] Add tests --- pkcs7/hashable_test.go | 105 +++++++++++++++++++++++++ pkcs7/sign_test.go | 93 +++++++++++++++------- pkcs7/testdata/{test.crt => test1.crt} | 0 pkcs7/testdata/{test.csr => test1.csr} | 0 pkcs7/testdata/{test.key => test1.key} | 0 pkcs7/testdata/{test.txt => test1.txt} | 0 6 files changed, 168 insertions(+), 30 deletions(-) create mode 100644 pkcs7/hashable_test.go rename pkcs7/testdata/{test.crt => test1.crt} (100%) rename pkcs7/testdata/{test.csr => test1.csr} (100%) rename pkcs7/testdata/{test.key => test1.key} (100%) rename pkcs7/testdata/{test.txt => test1.txt} (100%) diff --git a/pkcs7/hashable_test.go b/pkcs7/hashable_test.go new file mode 100644 index 0000000..785a6b9 --- /dev/null +++ b/pkcs7/hashable_test.go @@ -0,0 +1,105 @@ +package pkcs7 + +import ( + "bytes" + "os" + "testing" +) + +func Test_NewHashableReader(t *testing.T) { + cases := []struct { + FileName string + Hash []byte + Error string + }{ + { + FileName: "testdata/test1.txt", + Hash: []byte{ + 112, 80, 230, 94, 235, 41, 94, 59, + 18, 172, 134, 98, 53, 154, 178, 111, + 36, 89, 195, 198, 55, 200, 95, 36, + 193, 157, 229, 137, 123, 224, 99, 221, + }, + Error: "", + }, + } + + for _, c := range cases { + f, err := os.Open(c.FileName) + if err != nil { + t.Errorf("%v", err.Error()) + continue + } + defer f.Close() + + hashable := NewHashableReader(f) + if hashable == nil { + t.Errorf("Got nil from NewHashableReader(\"%v\")") + continue + } + + hash, err := hashable.Hash() + if c.Error != "" { + if err != nil && err.Error() == c.Error { + continue + } + + t.Errorf("Expected Error %v, found %v", c.Error, err) + continue + } + + if l := len(hash); l != 32 { + t.Errorf("len(hash) must be 32, found %v", l) + continue + } + + if !bytes.Equal(hash, c.Hash) { + t.Errorf("Expected hash %v for file %v, found %v", c.Hash, c.FileName, hash) + } + } +} + +func Test_NewHashableBytes(t *testing.T) { + cases := []struct { + Data []byte + Hash []byte + Error string + }{ + { + Data: []byte("Hello World!"), + Hash: []byte{ + 127, 131, 177, 101, 127, 241, 252, 83, 185, 45, + 193, 129, 72, 161, 214, 93, 252, 45, 75, 31, 163, + 214, 119, 40, 74, 221, 210, 0, 18, 109, 144, 105, + }, + Error: "", + }, + } + + for i, c := range cases { + hashable := NewHashableBytes(c.Data) + if hashable == nil { + t.Errorf("Got nil from NewHashableReader(\"%v\")") + continue + } + + hash, err := hashable.Hash() + if c.Error != "" { + if err != nil && err.Error() == c.Error { + continue + } + + t.Errorf("Expected Error %v, found %v", c.Error, err) + continue + } + + if l := len(hash); l != 32 { + t.Errorf("len(hash) must be 32, found %v", l) + continue + } + + if !bytes.Equal(hash, c.Hash) { + t.Errorf("Expected hash %v for test %v, found %v", c.Hash, i, hash) + } + } +} diff --git a/pkcs7/sign_test.go b/pkcs7/sign_test.go index 559e2c9..8fa8dcc 100644 --- a/pkcs7/sign_test.go +++ b/pkcs7/sign_test.go @@ -14,9 +14,9 @@ import ( // // Test key and certificate are in testdata/ and were generated with OpenSSL as follows: // -// openssl genrsa -out test.key 2048 -// openssl req -nodes -new -key test.key -out test.csr -subj "/C=CA/ST=Ontario/L=Toronto/O=Stefan Arentz/OU=Golang Hacks/CN=example.com" -// openssl x509 -req -days 1825 -in test.csr -signkey test.key -out test.crt +// openssl genrsa -out test1.key 2048 +// openssl req -nodes -new -key test1.key -out test1.csr -subj "/C=CA/ST=Ontario/L=Toronto/O=Stefan Arentz/OU=Golang Hacks/CN=example.com" +// openssl x509 -req -days 1825 -in test1.csr -signkey test1.key -out test1.crt // func loadPKCS1PrivateKey(path string) (*rsa.PrivateKey, error) { @@ -49,44 +49,77 @@ func loadCertificate(path string) (*x509.Certificate, error) { return x509.ParseCertificate(block.Bytes) } -func Test_Sign(t *testing.T) { - key, err := loadPKCS1PrivateKey("testdata/test.key") - if err != nil { - panic(err) +func verifySignature(file string, signature []byte) error { + if err := ioutil.WriteFile("/tmp/signature", signature, 0600); err != nil { + return err } - cert, err := loadCertificate("testdata/test.crt") - if err != nil { - panic(err) + cmd := exec.Command("openssl", "smime", "-verify", "-in", "/tmp/signature", "-content", file, "-inform", "der", "-noverify") + if err := cmd.Start(); err != nil { + return err } - f, err := os.Open("testdata/test.txt") - if err != nil { - panic(err) + if err := cmd.Wait(); err != nil { + return err } - defer f.Close() - signature, err := Sign(f, cert, key) - if err != nil { - t.Error("Cannot Sign:", err) - } + return nil +} - if len(signature) == 0 { - t.Error("Signature is zero length") +func Test_Sign(t *testing.T) { + cases := []struct { + FileName string + Certificate string + PrivateKey string + Error string + }{ + { + FileName: "testdata/test1.txt", + Certificate: "testdata/test1.crt", + PrivateKey: "testdata/test1.key", + Error: "", + }, } - // Verify the signature with OpenSSL + for _, c := range cases { + cert, err := loadCertificate(c.Certificate) + if err != nil { + t.Errorf("%v", err.Error()) + continue + } - if err := ioutil.WriteFile("/tmp/signature", signature, 0600); err != nil { - panic(err) - } + key, err := loadPKCS1PrivateKey(c.PrivateKey) + if err != nil { + t.Errorf("%v", err.Error()) + continue + } - cmd := exec.Command("openssl", "smime", "-verify", "-in", "/tmp/signature", "-content", "testdata/test.txt", "-inform", "der", "-noverify") - if err := cmd.Start(); err != nil { - t.Error("Failed to start openssl:", err) - } + f, err := os.Open(c.FileName) + if err != nil { + t.Errorf("%v", err.Error()) + continue + } + defer f.Close() - if err := cmd.Wait(); err != nil { - t.Error("Failed to verify signature with openssl:", err) + signature, err := Sign(f, cert, key) + + if c.Error != "" { + // Sign should fail + if err != nil && err.Error() == c.Error { + continue + } + + t.Errorf("Expected Error %v, found %v", c.Error, err) + continue + } + + if len(signature) <= 0 { + t.Errorf("Signature is zero length") + continue + } + + if err := verifySignature(c.FileName, signature); err != nil { + t.Errorf("Failed to verify signature with openssl: %v", err.Error()) + } } } diff --git a/pkcs7/testdata/test.crt b/pkcs7/testdata/test1.crt similarity index 100% rename from pkcs7/testdata/test.crt rename to pkcs7/testdata/test1.crt diff --git a/pkcs7/testdata/test.csr b/pkcs7/testdata/test1.csr similarity index 100% rename from pkcs7/testdata/test.csr rename to pkcs7/testdata/test1.csr diff --git a/pkcs7/testdata/test.key b/pkcs7/testdata/test1.key similarity index 100% rename from pkcs7/testdata/test.key rename to pkcs7/testdata/test1.key diff --git a/pkcs7/testdata/test.txt b/pkcs7/testdata/test1.txt similarity index 100% rename from pkcs7/testdata/test.txt rename to pkcs7/testdata/test1.txt From 629e3bb2491d871ad599c282b418346f085209fd Mon Sep 17 00:00:00 2001 From: Yannic Bonenberger Date: Tue, 10 Jan 2017 20:40:26 +0100 Subject: [PATCH 5/6] Add documentation --- pkcs7/hashable.go | 2 ++ pkcs7/sign.go | 16 ++++++++-------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/pkcs7/hashable.go b/pkcs7/hashable.go index 76243ac..94abc35 100644 --- a/pkcs7/hashable.go +++ b/pkcs7/hashable.go @@ -23,6 +23,7 @@ func (h *hashableReader) Hash() ([]byte, error) { return hash.Sum(nil), nil } +// Creates a new Hashable from io.Reader func NewHashableReader(r io.Reader) Hashable { return &hashableReader{r: r} } @@ -37,6 +38,7 @@ func (h *hashableBytes) Hash() ([]byte, error) { return hash.Sum(nil), nil } +// Creates a new Hashable from bytes func NewHashableBytes(b []byte) Hashable { return &hashableBytes{b: b} } diff --git a/pkcs7/sign.go b/pkcs7/sign.go index 64960a6..2d8373d 100644 --- a/pkcs7/sign.go +++ b/pkcs7/sign.go @@ -15,28 +15,28 @@ import ( "time" ) -// Create signature from Reader -// Returns signature and any error encountered. +// Create a signature from io.Reader +// Returns the signature and any error encountered. func Sign(reader io.Reader, certificate *x509.Certificate, privateKey *rsa.PrivateKey) ([]byte, error) { hashable := NewHashableReader(reader) return SignDataIntermediate(hashable, certificate, privateKey, nil) } -// Create signature from Reader including intermediate certificates. -// Returns signature and any error encountered. +// Create a signature from io.Reader including intermediate certificates. +// Returns the signature and any error encountered. func SignIntermediate(reader io.Reader, certificate *x509.Certificate, privateKey *rsa.PrivateKey, intermediateCertificates []*x509.Certificate) ([]byte, error) { hashable := NewHashableReader(reader) return SignDataIntermediate(hashable, certificate, privateKey, intermediateCertificates) } -// Creates signature -// Returns signature and any error encountered. +// Creates a signature +// Returns the signature and any error encountered. func SignData(hashable Hashable, certificate *x509.Certificate, privateKey *rsa.PrivateKey) ([]byte, error) { return SignDataIntermediate(hashable, certificate, privateKey, nil) } -// Create signature including intermediate certificates. -// Returns signature and any error encountered. +// Create a signature including intermediate certificates. +// Returns the signature and any error encountered. func SignDataIntermediate(hashable Hashable, certificate *x509.Certificate, privateKey *rsa.PrivateKey, intermediateCertificates []*x509.Certificate) ([]byte, error) { // Check if parameters are valid if certificate == nil { From 5af355dc7527233d43421e6e67b84945d772702c Mon Sep 17 00:00:00 2001 From: Yannic Bonenberger Date: Tue, 10 Jan 2017 20:55:42 +0100 Subject: [PATCH 6/6] Change interface Hashable for clarification --- pkcs7/hashable.go | 6 +++--- pkcs7/hashable_test.go | 4 ++-- pkcs7/sign.go | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pkcs7/hashable.go b/pkcs7/hashable.go index 94abc35..748cd94 100644 --- a/pkcs7/hashable.go +++ b/pkcs7/hashable.go @@ -6,14 +6,14 @@ import ( ) type Hashable interface { - Hash() ([]byte, error) + Sha256() ([]byte, error) } type hashableReader struct { r io.Reader } -func (h *hashableReader) Hash() ([]byte, error) { +func (h *hashableReader) Sha256() ([]byte, error) { hash := sha256.New() if _, err := io.Copy(hash, h.r); err != nil { @@ -32,7 +32,7 @@ type hashableBytes struct { b []byte } -func (h *hashableBytes) Hash() ([]byte, error) { +func (h *hashableBytes) Sha256() ([]byte, error) { hash := sha256.New() hash.Write(h.b) return hash.Sum(nil), nil diff --git a/pkcs7/hashable_test.go b/pkcs7/hashable_test.go index 785a6b9..43c96ca 100644 --- a/pkcs7/hashable_test.go +++ b/pkcs7/hashable_test.go @@ -38,7 +38,7 @@ func Test_NewHashableReader(t *testing.T) { continue } - hash, err := hashable.Hash() + hash, err := hashable.Sha256() if c.Error != "" { if err != nil && err.Error() == c.Error { continue @@ -83,7 +83,7 @@ func Test_NewHashableBytes(t *testing.T) { continue } - hash, err := hashable.Hash() + hash, err := hashable.Sha256() if c.Error != "" { if err != nil && err.Error() == c.Error { continue diff --git a/pkcs7/sign.go b/pkcs7/sign.go index 2d8373d..f3cce66 100644 --- a/pkcs7/sign.go +++ b/pkcs7/sign.go @@ -47,7 +47,7 @@ func SignDataIntermediate(hashable Hashable, certificate *x509.Certificate, priv return nil, errors.New("\"privateKey\" cannot be nil.") } - messageDigest, err := hashable.Hash() + messageDigest, err := hashable.Sha256() if err != nil { return nil, err } @@ -120,7 +120,7 @@ func SignDataIntermediate(hashable Hashable, certificate *x509.Certificate, priv encodedAuthenticatedAttributes[0] = 0x31 digest := NewHashableBytes(encodedAuthenticatedAttributes) - attributesDigest, err := digest.Hash() + attributesDigest, err := digest.Sha256() if err != nil { return nil, err }