summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/keybase/go-crypto/openpgp/packet/signature.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/keybase/go-crypto/openpgp/packet/signature.go')
-rw-r--r--vendor/github.com/keybase/go-crypto/openpgp/packet/signature.go91
1 files changed, 67 insertions, 24 deletions
diff --git a/vendor/github.com/keybase/go-crypto/openpgp/packet/signature.go b/vendor/github.com/keybase/go-crypto/openpgp/packet/signature.go
index 46224ad66d..383a8a6a39 100644
--- a/vendor/github.com/keybase/go-crypto/openpgp/packet/signature.go
+++ b/vendor/github.com/keybase/go-crypto/openpgp/packet/signature.go
@@ -10,6 +10,7 @@ import (
"crypto/dsa"
"crypto/ecdsa"
"encoding/binary"
+ "fmt"
"hash"
"io"
"strconv"
@@ -384,18 +385,20 @@ func parseSignatureSubpacket(sig *Signature, subpacket []byte, isHashed bool) (r
err = errors.StructuralError("empty key flags subpacket")
return
}
- sig.FlagsValid = true
- if subpacket[0]&KeyFlagCertify != 0 {
- sig.FlagCertify = true
- }
- if subpacket[0]&KeyFlagSign != 0 {
- sig.FlagSign = true
- }
- if subpacket[0]&KeyFlagEncryptCommunications != 0 {
- sig.FlagEncryptCommunications = true
- }
- if subpacket[0]&KeyFlagEncryptStorage != 0 {
- sig.FlagEncryptStorage = true
+ if subpacket[0] != 0 {
+ sig.FlagsValid = true
+ if subpacket[0]&KeyFlagCertify != 0 {
+ sig.FlagCertify = true
+ }
+ if subpacket[0]&KeyFlagSign != 0 {
+ sig.FlagSign = true
+ }
+ if subpacket[0]&KeyFlagEncryptCommunications != 0 {
+ sig.FlagEncryptCommunications = true
+ }
+ if subpacket[0]&KeyFlagEncryptStorage != 0 {
+ sig.FlagEncryptStorage = true
+ }
}
case reasonForRevocationSubpacket:
// Reason For Revocation, section 5.2.3.23
@@ -624,6 +627,13 @@ func (sig *Signature) Sign(h hash.Hash, priv *PrivateKey, config *Config) (err e
return
}
+ // Parameter check, if this is wrong we will make a signature but
+ // not serialize it later.
+ if sig.PubKeyAlgo != priv.PubKeyAlgo {
+ err = errors.InvalidArgumentError("signature pub key algo does not match priv key")
+ return
+ }
+
switch priv.PubKeyAlgo {
case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
sig.RSASignature.bytes, err = rsa.SignPKCS1v15(config.Random(), priv.PrivateKey.(*rsa.PrivateKey), sig.Hash, digest)
@@ -637,26 +647,29 @@ func (sig *Signature) Sign(h hash.Hash, priv *PrivateKey, config *Config) (err e
digest = digest[:subgroupSize]
}
r, s, err := dsa.Sign(config.Random(), dsaPriv, digest)
- if err == nil {
- sig.DSASigR.bytes = r.Bytes()
- sig.DSASigR.bitLength = uint16(8 * len(sig.DSASigR.bytes))
- sig.DSASigS.bytes = s.Bytes()
- sig.DSASigS.bitLength = uint16(8 * len(sig.DSASigS.bytes))
+ if err != nil {
+ return err
}
+ sig.DSASigR.bytes = r.Bytes()
+ sig.DSASigR.bitLength = uint16(8 * len(sig.DSASigR.bytes))
+ sig.DSASigS.bytes = s.Bytes()
+ sig.DSASigS.bitLength = uint16(8 * len(sig.DSASigS.bytes))
case PubKeyAlgoECDSA:
r, s, err := ecdsa.Sign(config.Random(), priv.PrivateKey.(*ecdsa.PrivateKey), digest)
- if err == nil {
- sig.ECDSASigR = FromBig(r)
- sig.ECDSASigS = FromBig(s)
+ if err != nil {
+ return err
}
+ sig.ECDSASigR = FromBig(r)
+ sig.ECDSASigS = FromBig(s)
case PubKeyAlgoEdDSA:
r, s, err := priv.PrivateKey.(*EdDSAPrivateKey).Sign(digest)
- if err == nil {
- sig.EdDSASigR = FromBytes(r)
- sig.EdDSASigS = FromBytes(s)
+ if err != nil {
+ return err
}
+ sig.EdDSASigR = FromBytes(r)
+ sig.EdDSASigS = FromBytes(s)
default:
- err = errors.UnsupportedError("public key algorithm: " + strconv.Itoa(int(sig.PubKeyAlgo)))
+ err = errors.UnsupportedError("public key algorithm for signing: " + strconv.Itoa(int(priv.PubKeyAlgo)))
}
return
@@ -704,6 +717,28 @@ func (sig *Signature) SignKeyWithSigner(signeePubKey *PublicKey, signerPubKey *P
return sig.Sign(s, nil, config)
}
+// CrossSignKey creates PrimaryKeyBinding signature in sig.EmbeddedSignature by
+// signing `primary` key's hash using `priv` subkey private key. Primary public
+// key is the `signee` here.
+func (sig *Signature) CrossSignKey(primary *PublicKey, priv *PrivateKey, config *Config) error {
+ if len(sig.outSubpackets) > 0 {
+ return fmt.Errorf("outSubpackets already exists, looks like CrossSignKey was called after Sign")
+ }
+
+ sig.EmbeddedSignature = &Signature{
+ CreationTime: sig.CreationTime,
+ SigType: SigTypePrimaryKeyBinding,
+ PubKeyAlgo: priv.PubKeyAlgo,
+ Hash: sig.Hash,
+ }
+
+ h, err := keySignatureHash(primary, &priv.PublicKey, sig.Hash)
+ if err != nil {
+ return err
+ }
+ return sig.EmbeddedSignature.Sign(h, priv, config)
+}
+
// Serialize marshals sig to w. Sign, SignUserId or SignKey must have been
// called first.
func (sig *Signature) Serialize(w io.Writer) (err error) {
@@ -832,6 +867,14 @@ func (sig *Signature) buildSubpackets() (subpackets []outputSubpacket) {
subpackets = append(subpackets, outputSubpacket{true, prefCompressionSubpacket, false, sig.PreferredCompression})
}
+ if sig.EmbeddedSignature != nil {
+ buf := bytes.NewBuffer(nil)
+ if err := sig.EmbeddedSignature.Serialize(buf); err == nil {
+ byteContent := buf.Bytes()[2:] // skip 2-byte length header
+ subpackets = append(subpackets, outputSubpacket{false, embeddedSignatureSubpacket, true, byteContent})
+ }
+ }
+
return
}