func (pk *PrivateKey) parse(r io.Reader) (err error) { err = (&pk.PublicKey).parse(r) if err != nil { return } var buf [1]byte _, err = readFull(r, buf[:]) if err != nil { return } s2kType := buf[0] switch s2kType { case 0: pk.s2k = nil pk.Encrypted = false case 254, 255: _, err = readFull(r, buf[:]) if err != nil { return } pk.cipher = CipherFunction(buf[0]) pk.Encrypted = true pk.s2k, err = s2k.Parse(r) if err != nil { return } if s2kType == 254 { pk.sha1Checksum = true } default: return errors.UnsupportedError("deprecated s2k function in private key") } if pk.Encrypted { blockSize := pk.cipher.blockSize() if blockSize == 0 { return errors.UnsupportedError("unsupported cipher in private key: " + strconv.Itoa(int(pk.cipher))) } pk.iv = make([]byte, blockSize) _, err = readFull(r, pk.iv) if err != nil { return } } pk.encryptedData, err = ioutil.ReadAll(r) if err != nil { return } if !pk.Encrypted { return pk.parsePrivateKey(pk.encryptedData) } return }
func (ske *SymmetricKeyEncrypted) parse(r io.Reader) error { // RFC 4880, section 5.3. var buf [2]byte if _, err := readFull(r, buf[:]); err != nil { return err } if buf[0] != symmetricKeyEncryptedVersion { return errors.UnsupportedError("SymmetricKeyEncrypted version") } ske.CipherFunc = CipherFunction(buf[1]) if ske.CipherFunc.KeySize() == 0 { return errors.UnsupportedError("unknown cipher: " + strconv.Itoa(int(buf[1]))) } var err error ske.s2k, err = s2k.Parse(r) if err != nil { return err } if ske.s2k == nil { return errors.UnsupportedError("can't use dummy S2K for symmetric key encryption") } encryptedKey := make([]byte, maxSessionKeySizeInBytes) // The session key may follow. We just have to try and read to find // out. If it exists then we limit it to maxSessionKeySizeInBytes. n, err := readFull(r, encryptedKey) if err != nil && err != io.ErrUnexpectedEOF { return err } if n != 0 { if n == maxSessionKeySizeInBytes { return errors.UnsupportedError("oversized encrypted session key") } ske.encryptedKey = encryptedKey[:n] } return nil }
func (pk *PrivateKey) parse(r io.Reader) (err error) { err = (&pk.PublicKey).parse(r) if err != nil { return } var buf [1]byte _, err = readFull(r, buf[:]) if err != nil { return } s2kType := buf[0] switch s2kType { case 0: pk.s2k = nil pk.Encrypted = false case 254, 255: _, err = readFull(r, buf[:]) if err != nil { return } pk.cipher = CipherFunction(buf[0]) pk.Encrypted = true pk.s2k, err = s2k.Parse(r) if err != nil { return } if s2kType == 254 { pk.sha1Checksum = true } // S2K == nil implies that we got a "GNU Dummy" S2K. For instance, // because our master secret key is on a USB key in a vault somewhere. // In that case, there is no further data to consume here. if pk.s2k == nil { pk.Encrypted = false return } default: return errors.UnsupportedError("deprecated s2k function in private key") } if pk.Encrypted { blockSize := pk.cipher.blockSize() if blockSize == 0 { return errors.UnsupportedError("unsupported cipher in private key: " + strconv.Itoa(int(pk.cipher))) } pk.iv = make([]byte, blockSize) _, err = readFull(r, pk.iv) if err != nil { return } } pk.encryptedData, err = ioutil.ReadAll(r) if err != nil { return } if !pk.Encrypted { return pk.parsePrivateKey(pk.encryptedData) } return }