diff options
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.go | 91 |
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 } |