func (ops *OnePassSignature) parse(r io.Reader) (err error) { var buf [13]byte _, err = readFull(r, buf[:]) if err != nil { return } if buf[0] != onePassSignatureVersion { err = errors.UnsupportedError("one-pass-signature packet version " + strconv.Itoa(int(buf[0]))) } var ok bool ops.Hash, ok = s2k.HashIdToHash(buf[2]) if !ok { return errors.UnsupportedError("hash function: " + strconv.Itoa(int(buf[2]))) } ops.SigType = SignatureType(buf[1]) ops.PubKeyAlgo = PublicKeyAlgorithm(buf[3]) ops.KeyId = binary.BigEndian.Uint64(buf[4:12]) ops.IsLast = buf[12] != 0 return }
func (sig *Signature) parse(r io.Reader) (err error) { // RFC 4880, section 5.2.3 var buf [5]byte _, err = readFull(r, buf[:1]) if err != nil { return } if buf[0] != 4 { err = errors.UnsupportedError("signature packet version " + strconv.Itoa(int(buf[0]))) return } _, err = readFull(r, buf[:5]) if err != nil { return } sig.SigType = SignatureType(buf[0]) sig.PubKeyAlgo = PublicKeyAlgorithm(buf[1]) switch sig.PubKeyAlgo { case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly, PubKeyAlgoDSA, PubKeyAlgoECDSA: default: err = errors.UnsupportedError("public key algorithm " + strconv.Itoa(int(sig.PubKeyAlgo))) return } var ok bool sig.Hash, ok = s2k.HashIdToHash(buf[2]) if !ok { return errors.UnsupportedError("hash function " + strconv.Itoa(int(buf[2]))) } hashedSubpacketsLength := int(buf[3])<<8 | int(buf[4]) l := 6 + hashedSubpacketsLength sig.HashSuffix = make([]byte, l+6) sig.HashSuffix[0] = 4 copy(sig.HashSuffix[1:], buf[:5]) hashedSubpackets := sig.HashSuffix[6:l] _, err = readFull(r, hashedSubpackets) if err != nil { return } // See RFC 4880, section 5.2.4 trailer := sig.HashSuffix[l:] trailer[0] = 4 trailer[1] = 0xff trailer[2] = uint8(l >> 24) trailer[3] = uint8(l >> 16) trailer[4] = uint8(l >> 8) trailer[5] = uint8(l) err = parseSignatureSubpackets(sig, hashedSubpackets, true) if err != nil { return } _, err = readFull(r, buf[:2]) if err != nil { return } unhashedSubpacketsLength := int(buf[0])<<8 | int(buf[1]) unhashedSubpackets := make([]byte, unhashedSubpacketsLength) _, err = readFull(r, unhashedSubpackets) if err != nil { return } err = parseSignatureSubpackets(sig, unhashedSubpackets, false) if err != nil { return } _, err = readFull(r, sig.HashTag[:2]) if err != nil { return } switch sig.PubKeyAlgo { case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly: sig.RSASignature.bytes, sig.RSASignature.bitLength, err = readMPI(r) case PubKeyAlgoDSA: sig.DSASigR.bytes, sig.DSASigR.bitLength, err = readMPI(r) if err == nil { sig.DSASigS.bytes, sig.DSASigS.bitLength, err = readMPI(r) } case PubKeyAlgoECDSA: sig.ECDSASigR.bytes, sig.ECDSASigR.bitLength, err = readMPI(r) if err == nil { sig.ECDSASigS.bytes, sig.ECDSASigS.bitLength, err = readMPI(r) } default: panic("unreachable") } return }
func (sig *SignatureV3) parse(r io.Reader) (err error) { // RFC 4880, section 5.2.2 var buf [8]byte if _, err = readFull(r, buf[:1]); err != nil { return } if buf[0] < 2 || buf[0] > 3 { err = errors.UnsupportedError("signature packet version " + strconv.Itoa(int(buf[0]))) return } if _, err = readFull(r, buf[:1]); err != nil { return } if buf[0] != 5 { err = errors.UnsupportedError( "invalid hashed material length " + strconv.Itoa(int(buf[0]))) return } // Read hashed material: signature type + creation time if _, err = readFull(r, buf[:5]); err != nil { return } sig.SigType = SignatureType(buf[0]) t := binary.BigEndian.Uint32(buf[1:5]) sig.CreationTime = time.Unix(int64(t), 0) // Eight-octet Key ID of signer. if _, err = readFull(r, buf[:8]); err != nil { return } sig.IssuerKeyId = binary.BigEndian.Uint64(buf[:]) // Public-key and hash algorithm if _, err = readFull(r, buf[:2]); err != nil { return } sig.PubKeyAlgo = PublicKeyAlgorithm(buf[0]) switch sig.PubKeyAlgo { case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly, PubKeyAlgoDSA: default: err = errors.UnsupportedError("public key algorithm " + strconv.Itoa(int(sig.PubKeyAlgo))) return } var ok bool if sig.Hash, ok = s2k.HashIdToHash(buf[1]); !ok { return errors.UnsupportedError("hash function " + strconv.Itoa(int(buf[2]))) } // Two-octet field holding left 16 bits of signed hash value. if _, err = readFull(r, sig.HashTag[:2]); err != nil { return } switch sig.PubKeyAlgo { case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly: sig.RSASignature.bytes, sig.RSASignature.bitLength, err = readMPI(r) case PubKeyAlgoDSA: if sig.DSASigR.bytes, sig.DSASigR.bitLength, err = readMPI(r); err != nil { return } sig.DSASigS.bytes, sig.DSASigS.bitLength, err = readMPI(r) default: panic("unreachable") } return }