예제 #1
0
파일: keys.go 프로젝트: go-nosql/golang
func addSubkey(e *Entity, packets *packet.Reader, pub *packet.PublicKey, priv *packet.PrivateKey) os.Error {
	var subKey Subkey
	subKey.PublicKey = pub
	subKey.PrivateKey = priv
	p, err := packets.Next()
	if err == os.EOF {
		return io.ErrUnexpectedEOF
	}
	if err != nil {
		return error.StructuralError("subkey signature invalid: " + err.String())
	}
	var ok bool
	subKey.Sig, ok = p.(*packet.Signature)
	if !ok {
		return error.StructuralError("subkey packet not followed by signature")
	}
	if subKey.Sig.SigType != packet.SigTypeSubkeyBinding {
		return error.StructuralError("subkey signature with wrong type")
	}
	err = e.PrimaryKey.VerifyKeySignature(subKey.PublicKey, subKey.Sig)
	if err != nil {
		return error.StructuralError("subkey signature invalid: " + err.String())
	}
	e.Subkeys = append(e.Subkeys, subKey)
	return nil
}
예제 #2
0
파일: read.go 프로젝트: richlowe/gcc
func (scr *signatureCheckReader) Read(buf []byte) (n int, err os.Error) {
	n, err = scr.md.LiteralData.Body.Read(buf)
	scr.wrappedHash.Write(buf[:n])
	if err == os.EOF {
		var p packet.Packet
		p, scr.md.SignatureError = scr.packets.Next()
		if scr.md.SignatureError != nil {
			return
		}

		var ok bool
		if scr.md.Signature, ok = p.(*packet.Signature); !ok {
			scr.md.SignatureError = error.StructuralError("LiteralData not followed by Signature")
			return
		}

		scr.md.SignatureError = scr.md.SignedBy.PublicKey.VerifySignature(scr.h, scr.md.Signature)

		// The SymmetricallyEncrypted packet, if any, might have an
		// unsigned hash of its own. In order to check this we need to
		// close that Reader.
		if scr.md.decrypted != nil {
			mdcErr := scr.md.decrypted.Close()
			if mdcErr != nil {
				err = mdcErr
			}
		}
	}
	return
}
예제 #3
0
// Decrypt attempts to decrypt an encrypted session key. If it returns nil,
// ske.Key will contain the session key.
func (ske *SymmetricKeyEncrypted) Decrypt(passphrase []byte) os.Error {
	if !ske.Encrypted {
		return nil
	}

	key := make([]byte, ske.CipherFunc.KeySize())
	ske.s2k(key, passphrase)

	if len(ske.encryptedKey) == 0 {
		ske.Key = key
	} else {
		// the IV is all zeros
		iv := make([]byte, ske.CipherFunc.blockSize())
		c := cipher.NewCFBDecrypter(ske.CipherFunc.new(key), iv)
		c.XORKeyStream(ske.encryptedKey, ske.encryptedKey)
		ske.CipherFunc = CipherFunction(ske.encryptedKey[0])
		if ske.CipherFunc.blockSize() == 0 {
			return error.UnsupportedError("unknown cipher: " + strconv.Itoa(int(ske.CipherFunc)))
		}
		ske.CipherFunc = CipherFunction(ske.encryptedKey[0])
		ske.Key = ske.encryptedKey[1:]
		if len(ske.Key)%ske.CipherFunc.blockSize() != 0 {
			ske.Key = nil
			return error.StructuralError("length of decrypted key not a multiple of block size")
		}
	}

	ske.Encrypted = false
	return nil
}
예제 #4
0
// Decrypt decrypts an encrypted session key with the given private key. The
// private key must have been decrypted first.
func (e *EncryptedKey) Decrypt(priv *PrivateKey) error {
	var err error
	var b []byte

	// TODO(agl): use session key decryption routines here to avoid
	// padding oracle attacks.
	switch priv.PubKeyAlgo {
	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly:
		b, err = rsa.DecryptPKCS1v15(rand.Reader, priv.PrivateKey.(*rsa.PrivateKey), e.encryptedMPI1)
	case PubKeyAlgoElGamal:
		c1 := new(big.Int).SetBytes(e.encryptedMPI1)
		c2 := new(big.Int).SetBytes(e.encryptedMPI2)
		b, err = elgamal.Decrypt(priv.PrivateKey.(*elgamal.PrivateKey), c1, c2)
	default:
		err = error_.InvalidArgumentError("cannot decrypted encrypted session key with private key of type " + strconv.Itoa(int(priv.PubKeyAlgo)))
	}

	if err != nil {
		return err
	}

	e.CipherFunc = CipherFunction(b[0])
	e.Key = b[1 : len(b)-2]
	expectedChecksum := uint16(b[len(b)-2])<<8 | uint16(b[len(b)-1])
	checksum := checksumKeyMaterial(e.Key)
	if checksum != expectedChecksum {
		return error_.StructuralError("EncryptedKey checksum incorrect")
	}

	return nil
}
예제 #5
0
파일: packet.go 프로젝트: marsch/camlistore
func readHeader(r io.Reader) (tag uint8, length uint64, err os.Error) {
	var buf [4]byte
	_, err = io.ReadFull(r, buf[0:1])
	if err != nil {
		return
	}
	if buf[0]&0x80 == 0 {
		err = error.StructuralError("tag byte does not have MSB set")
		return
	}
	if buf[0]&0x40 == 0 {
		// Old format packet
		tag = (buf[0] & 0x3f) >> 2
		lengthType := buf[0] & 3
		if lengthType == 3 {
			err = error.Unsupported("indeterminate length packet")
			return
		}
		lengthBytes := 1 << lengthType
		_, err = io.ReadFull(r, buf[0:lengthBytes])
		if err != nil {
			return
		}
		for i := 0; i < lengthBytes; i++ {
			length <<= 8
			length |= uint64(buf[i])
		}
		return
	}

	// New format packet
	tag = buf[0] & 0x3f
	_, err = io.ReadFull(r, buf[0:1])
	if err != nil {
		return
	}
	switch {
	case buf[0] < 192:
		length = uint64(buf[0])
	case buf[0] < 224:
		length = uint64(buf[0]-192) << 8
		_, err = io.ReadFull(r, buf[0:1])
		if err != nil {
			return
		}
		length += uint64(buf[0]) + 192
	case buf[0] < 255:
		err = error.Unsupported("chunked packet")
	default:
		_, err := io.ReadFull(r, buf[0:4])
		if err != nil {
			return
		}
		length = uint64(buf[0])<<24 |
			uint64(buf[1])<<16 |
			uint64(buf[2])<<8 |
			uint64(buf[3])
	}
	return
}
예제 #6
0
파일: read.go 프로젝트: richlowe/gcc
// CheckDetachedSignature takes a signed file and a detached signature and
// returns the signer if the signature is valid. If the signer isn't know,
// UnknownIssuerError is returned.
func CheckDetachedSignature(keyring KeyRing, signed, signature io.Reader) (signer *Entity, err os.Error) {
	p, err := packet.Read(signature)
	if err != nil {
		return
	}

	sig, ok := p.(*packet.Signature)
	if !ok {
		return nil, error.StructuralError("non signature packet found")
	}

	if sig.IssuerKeyId == nil {
		return nil, error.StructuralError("signature doesn't have an issuer")
	}

	keys := keyring.KeysById(*sig.IssuerKeyId)
	if len(keys) == 0 {
		return nil, error.UnknownIssuerError
	}

	h, wrappedHash, err := hashForSignature(sig.Hash, sig.SigType)
	if err != nil {
		return
	}

	_, err = io.Copy(wrappedHash, signed)
	if err != nil && err != os.EOF {
		return
	}

	for _, key := range keys {
		if key.SelfSignature.FlagsValid && !key.SelfSignature.FlagSign {
			continue
		}
		err = key.PublicKey.VerifySignature(h, sig)
		if err == nil {
			return key.Entity, nil
		}
	}

	if err != nil {
		return
	}

	return nil, error.UnknownIssuerError
}
예제 #7
0
파일: private_key.go 프로젝트: richlowe/gcc
// Decrypt decrypts an encrypted private key using a passphrase.
func (pk *PrivateKey) Decrypt(passphrase []byte) os.Error {
	if !pk.Encrypted {
		return nil
	}

	key := make([]byte, pk.cipher.keySize())
	pk.s2k(key, passphrase)
	block := pk.cipher.new(key)
	cfb := cipher.NewCFBDecrypter(block, pk.iv)

	data := pk.encryptedData
	cfb.XORKeyStream(data, data)

	if pk.sha1Checksum {
		if len(data) < sha1.Size {
			return error.StructuralError("truncated private key data")
		}
		h := sha1.New()
		h.Write(data[:len(data)-sha1.Size])
		sum := h.Sum()
		if !bytes.Equal(sum, data[len(data)-sha1.Size:]) {
			return error.StructuralError("private key checksum failure")
		}
		data = data[:len(data)-sha1.Size]
	} else {
		if len(data) < 2 {
			return error.StructuralError("truncated private key data")
		}
		var sum uint16
		for i := 0; i < len(data)-2; i++ {
			sum += uint16(data[i])
		}
		if data[len(data)-2] != uint8(sum>>8) ||
			data[len(data)-1] != uint8(sum) {
			return error.StructuralError("private key checksum failure")
		}
		data = data[:len(data)-2]
	}

	return pk.parsePrivateKey(data)
}
예제 #8
0
파일: signature.go 프로젝트: WXB506/golang
// parseSignatureSubpackets parses subpackets of the main signature packet. See
// RFC 4880, section 5.2.3.1.
func parseSignatureSubpackets(sig *Signature, subpackets []byte, isHashed bool) (err os.Error) {
	for len(subpackets) > 0 {
		subpackets, err = parseSignatureSubpacket(sig, subpackets, isHashed)
		if err != nil {
			return
		}
	}

	if sig.CreationTime == 0 {
		err = error.StructuralError("no creation time in signature")
	}

	return
}
예제 #9
0
파일: packet.go 프로젝트: richlowe/gcc
// readHeader parses a packet header and returns an io.Reader which will return
// the contents of the packet. See RFC 4880, section 4.2.
func readHeader(r io.Reader) (tag packetType, length int64, contents io.Reader, err os.Error) {
	var buf [4]byte
	_, err = io.ReadFull(r, buf[:1])
	if err != nil {
		return
	}
	if buf[0]&0x80 == 0 {
		err = error.StructuralError("tag byte does not have MSB set")
		return
	}
	if buf[0]&0x40 == 0 {
		// Old format packet
		tag = packetType((buf[0] & 0x3f) >> 2)
		lengthType := buf[0] & 3
		if lengthType == 3 {
			length = -1
			contents = r
			return
		}
		lengthBytes := 1 << lengthType
		_, err = readFull(r, buf[0:lengthBytes])
		if err != nil {
			return
		}
		for i := 0; i < lengthBytes; i++ {
			length <<= 8
			length |= int64(buf[i])
		}
		contents = &spanReader{r, length}
		return
	}

	// New format packet
	tag = packetType(buf[0] & 0x3f)
	length, isPartial, err := readLength(r)
	if err != nil {
		return
	}
	if isPartial {
		contents = &partialLengthReader{
			remaining: length,
			isPartial: true,
			r:         r,
		}
		length = -1
	} else {
		contents = &spanReader{r, length}
	}
	return
}
예제 #10
0
// DecryptRSA decrypts an RSA encrypted session key with the given private key.
func (e *EncryptedKey) DecryptRSA(priv *rsa.PrivateKey) (err os.Error) {
	if e.Algo != PubKeyAlgoRSA && e.Algo != PubKeyAlgoRSAEncryptOnly {
		return error.InvalidArgumentError("EncryptedKey not RSA encrypted")
	}
	b, err := rsa.DecryptPKCS1v15(rand.Reader, priv, e.Encrypted)
	if err != nil {
		return
	}
	e.CipherFunc = CipherFunction(b[0])
	e.Key = b[1 : len(b)-2]
	expectedChecksum := uint16(b[len(b)-2])<<8 | uint16(b[len(b)-1])
	var checksum uint16
	for _, v := range e.Key {
		checksum += uint16(v)
	}
	if checksum != expectedChecksum {
		return error.StructuralError("EncryptedKey checksum incorrect")
	}

	return
}
예제 #11
0
파일: keys.go 프로젝트: go-nosql/golang
// readEntity reads an entity (public key, identities, subkeys etc) from the
// given Reader.
func readEntity(packets *packet.Reader) (*Entity, os.Error) {
	e := new(Entity)
	e.Identities = make(map[string]*Identity)

	p, err := packets.Next()
	if err != nil {
		return nil, err
	}

	var ok bool
	if e.PrimaryKey, ok = p.(*packet.PublicKey); !ok {
		if e.PrivateKey, ok = p.(*packet.PrivateKey); !ok {
			packets.Unread(p)
			return nil, error.StructuralError("first packet was not a public/private key")
		} else {
			e.PrimaryKey = &e.PrivateKey.PublicKey
		}
	}

	var current *Identity
EachPacket:
	for {
		p, err := packets.Next()
		if err == os.EOF {
			break
		} else if err != nil {
			return nil, err
		}

		switch pkt := p.(type) {
		case *packet.UserId:
			current = new(Identity)
			current.Name = pkt.Id
			current.UserId = pkt
			e.Identities[pkt.Id] = current

			for {
				p, err = packets.Next()
				if err == os.EOF {
					return nil, io.ErrUnexpectedEOF
				} else if err != nil {
					return nil, err
				}

				sig, ok := p.(*packet.Signature)
				if !ok {
					return nil, error.StructuralError("user ID packet not followed by self-signature")
				}

				if sig.SigType == packet.SigTypePositiveCert && sig.IssuerKeyId != nil && *sig.IssuerKeyId == e.PrimaryKey.KeyId {
					if err = e.PrimaryKey.VerifyUserIdSignature(pkt.Id, sig); err != nil {
						return nil, error.StructuralError("user ID self-signature invalid: " + err.String())
					}
					current.SelfSignature = sig
					break
				}
				current.Signatures = append(current.Signatures, sig)
			}
		case *packet.Signature:
			if current == nil {
				return nil, error.StructuralError("signature packet found before user id packet")
			}
			current.Signatures = append(current.Signatures, pkt)
		case *packet.PrivateKey:
			if pkt.IsSubkey == false {
				packets.Unread(p)
				break EachPacket
			}
			err = addSubkey(e, packets, &pkt.PublicKey, pkt)
			if err != nil {
				return nil, err
			}
		case *packet.PublicKey:
			if pkt.IsSubkey == false {
				packets.Unread(p)
				break EachPacket
			}
			err = addSubkey(e, packets, pkt, nil)
			if err != nil {
				return nil, err
			}
		default:
			// we ignore unknown packets
		}
	}

	if len(e.Identities) == 0 {
		return nil, error.StructuralError("entity without any identities")
	}

	return e, nil
}
예제 #12
0
파일: signature.go 프로젝트: WXB506/golang
// parseSignatureSubpacket parses a single subpacket. len(subpacket) is >= 1.
func parseSignatureSubpacket(sig *Signature, subpacket []byte, isHashed bool) (rest []byte, err os.Error) {
	// RFC 4880, section 5.2.3.1
	var (
		length     uint32
		packetType signatureSubpacketType
		isCritical bool
	)
	switch {
	case subpacket[0] < 192:
		length = uint32(subpacket[0])
		subpacket = subpacket[1:]
	case subpacket[0] < 255:
		if len(subpacket) < 2 {
			goto Truncated
		}
		length = uint32(subpacket[0]-192)<<8 + uint32(subpacket[1]) + 192
		subpacket = subpacket[2:]
	default:
		if len(subpacket) < 5 {
			goto Truncated
		}
		length = uint32(subpacket[1])<<24 |
			uint32(subpacket[2])<<16 |
			uint32(subpacket[3])<<8 |
			uint32(subpacket[4])
		subpacket = subpacket[5:]
	}
	if length > uint32(len(subpacket)) {
		goto Truncated
	}
	rest = subpacket[length:]
	subpacket = subpacket[:length]
	if len(subpacket) == 0 {
		err = error.StructuralError("zero length signature subpacket")
		return
	}
	packetType = signatureSubpacketType(subpacket[0] & 0x7f)
	isCritical = subpacket[0]&0x80 == 0x80
	subpacket = subpacket[1:]
	sig.rawSubpackets = append(sig.rawSubpackets, outputSubpacket{isHashed, packetType, isCritical, subpacket})
	switch packetType {
	case creationTimeSubpacket:
		if !isHashed {
			err = error.StructuralError("signature creation time in non-hashed area")
			return
		}
		if len(subpacket) != 4 {
			err = error.StructuralError("signature creation time not four bytes")
			return
		}
		sig.CreationTime = binary.BigEndian.Uint32(subpacket)
	case signatureExpirationSubpacket:
		// Signature expiration time, section 5.2.3.10
		if !isHashed {
			return
		}
		if len(subpacket) != 4 {
			err = error.StructuralError("expiration subpacket with bad length")
			return
		}
		sig.SigLifetimeSecs = new(uint32)
		*sig.SigLifetimeSecs = binary.BigEndian.Uint32(subpacket)
	case keyExpirySubpacket:
		// Key expiration time, section 5.2.3.6
		if !isHashed {
			return
		}
		if len(subpacket) != 4 {
			err = error.StructuralError("key expiration subpacket with bad length")
			return
		}
		sig.KeyLifetimeSecs = new(uint32)
		*sig.KeyLifetimeSecs = binary.BigEndian.Uint32(subpacket)
	case prefSymmetricAlgosSubpacket:
		// Preferred symmetric algorithms, section 5.2.3.7
		if !isHashed {
			return
		}
		sig.PreferredSymmetric = make([]byte, len(subpacket))
		copy(sig.PreferredSymmetric, subpacket)
	case issuerSubpacket:
		// Issuer, section 5.2.3.5
		if len(subpacket) != 8 {
			err = error.StructuralError("issuer subpacket with bad length")
			return
		}
		sig.IssuerKeyId = new(uint64)
		*sig.IssuerKeyId = binary.BigEndian.Uint64(subpacket)
	case prefHashAlgosSubpacket:
		// Preferred hash algorithms, section 5.2.3.8
		if !isHashed {
			return
		}
		sig.PreferredHash = make([]byte, len(subpacket))
		copy(sig.PreferredHash, subpacket)
	case prefCompressionSubpacket:
		// Preferred compression algorithms, section 5.2.3.9
		if !isHashed {
			return
		}
		sig.PreferredCompression = make([]byte, len(subpacket))
		copy(sig.PreferredCompression, subpacket)
	case primaryUserIdSubpacket:
		// Primary User ID, section 5.2.3.19
		if !isHashed {
			return
		}
		if len(subpacket) != 1 {
			err = error.StructuralError("primary user id subpacket with bad length")
			return
		}
		sig.IsPrimaryId = new(bool)
		if subpacket[0] > 0 {
			*sig.IsPrimaryId = true
		}
	case keyFlagsSubpacket:
		// Key flags, section 5.2.3.21
		if !isHashed {
			return
		}
		if len(subpacket) == 0 {
			err = error.StructuralError("empty key flags subpacket")
			return
		}
		sig.FlagsValid = true
		if subpacket[0]&1 != 0 {
			sig.FlagCertify = true
		}
		if subpacket[0]&2 != 0 {
			sig.FlagSign = true
		}
		if subpacket[0]&4 != 0 {
			sig.FlagEncryptCommunications = true
		}
		if subpacket[0]&8 != 0 {
			sig.FlagEncryptStorage = true
		}

	default:
		if isCritical {
			err = error.UnsupportedError("unknown critical signature subpacket type " + strconv.Itoa(int(packetType)))
			return
		}
	}
	return

Truncated:
	err = error.StructuralError("signature subpacket truncated")
	return
}
예제 #13
0
파일: read.go 프로젝트: richlowe/gcc
// ReadMessage parses an OpenPGP message that may be signed and/or encrypted.
// The given KeyRing should contain both public keys (for signature
// verification) and, possibly encrypted, private keys for decrypting.
func ReadMessage(r io.Reader, keyring KeyRing, prompt PromptFunction) (md *MessageDetails, err os.Error) {
	var p packet.Packet

	var symKeys []*packet.SymmetricKeyEncrypted
	var pubKeys []keyEnvelopePair
	var se *packet.SymmetricallyEncrypted

	packets := packet.NewReader(r)
	md = new(MessageDetails)
	md.IsEncrypted = true

	// The message, if encrypted, starts with a number of packets
	// containing an encrypted decryption key. The decryption key is either
	// encrypted to a public key, or with a passphrase. This loop
	// collects these packets.
ParsePackets:
	for {
		p, err = packets.Next()
		if err != nil {
			return nil, err
		}
		switch p := p.(type) {
		case *packet.SymmetricKeyEncrypted:
			// This packet contains the decryption key encrypted with a passphrase.
			md.IsSymmetricallyEncrypted = true
			symKeys = append(symKeys, p)
		case *packet.EncryptedKey:
			// This packet contains the decryption key encrypted to a public key.
			md.EncryptedToKeyIds = append(md.EncryptedToKeyIds, p.KeyId)
			if p.Algo != packet.PubKeyAlgoRSA && p.Algo != packet.PubKeyAlgoRSAEncryptOnly {
				continue
			}
			var keys []Key
			if p.KeyId == 0 {
				keys = keyring.DecryptionKeys()
			} else {
				keys = keyring.KeysById(p.KeyId)
			}
			for _, k := range keys {
				pubKeys = append(pubKeys, keyEnvelopePair{k, p})
			}
		case *packet.SymmetricallyEncrypted:
			se = p
			break ParsePackets
		case *packet.Compressed, *packet.LiteralData, *packet.OnePassSignature:
			// This message isn't encrypted.
			if len(symKeys) != 0 || len(pubKeys) != 0 {
				return nil, error.StructuralError("key material not followed by encrypted message")
			}
			packets.Unread(p)
			return readSignedMessage(packets, nil, keyring)
		}
	}

	var candidates []Key
	var decrypted io.ReadCloser

	// Now that we have the list of encrypted keys we need to decrypt at
	// least one of them or, if we cannot, we need to call the prompt
	// function so that it can decrypt a key or give us a passphrase.
FindKey:
	for {
		// See if any of the keys already have a private key availible
		candidates = candidates[:0]
		candidateFingerprints := make(map[string]bool)

		for _, pk := range pubKeys {
			if pk.key.PrivateKey == nil {
				continue
			}
			if !pk.key.PrivateKey.Encrypted {
				if len(pk.encryptedKey.Key) == 0 {
					pk.encryptedKey.DecryptRSA(pk.key.PrivateKey.PrivateKey.(*rsa.PrivateKey))
				}
				if len(pk.encryptedKey.Key) == 0 {
					continue
				}
				decrypted, err = se.Decrypt(pk.encryptedKey.CipherFunc, pk.encryptedKey.Key)
				if err != nil && err != error.KeyIncorrectError {
					return nil, err
				}
				if decrypted != nil {
					md.DecryptedWith = pk.key
					break FindKey
				}
			} else {
				fpr := string(pk.key.PublicKey.Fingerprint[:])
				if v := candidateFingerprints[fpr]; v {
					continue
				}
				candidates = append(candidates, pk.key)
				candidateFingerprints[fpr] = true
			}
		}

		if len(candidates) == 0 && len(symKeys) == 0 {
			return nil, error.KeyIncorrectError
		}

		if prompt == nil {
			return nil, error.KeyIncorrectError
		}

		passphrase, err := prompt(candidates, len(symKeys) != 0)
		if err != nil {
			return nil, err
		}

		// Try the symmetric passphrase first
		if len(symKeys) != 0 && passphrase != nil {
			for _, s := range symKeys {
				err = s.Decrypt(passphrase)
				if err == nil && !s.Encrypted {
					decrypted, err = se.Decrypt(s.CipherFunc, s.Key)
					if err != nil && err != error.KeyIncorrectError {
						return nil, err
					}
					if decrypted != nil {
						break FindKey
					}
				}

			}
		}
	}

	md.decrypted = decrypted
	packets.Push(decrypted)
	return readSignedMessage(packets, md, keyring)
}
예제 #14
0
파일: armor.go 프로젝트: richlowe/gcc
//    base64-encoded Bytes
//    '=' base64 encoded checksum
//    -----END Type-----
// where Headers is a possibly empty sequence of Key: Value lines.
//
// Since the armored data can be very large, this package presents a streaming
// interface.
type Block struct {
	Type    string            // The type, taken from the preamble (i.e. "PGP SIGNATURE").
	Header  map[string]string // Optional headers.
	Body    io.Reader         // A Reader from which the contents can be read
	lReader lineReader
	oReader openpgpReader
}

var ArmorCorrupt os.Error = error.StructuralError("armor invalid")

const crc24Init = 0xb704ce
const crc24Poly = 0x1864cfb
const crc24Mask = 0xffffff

// crc24 calculates the OpenPGP checksum as specified in RFC 4880, section 6.1
func crc24(crc uint32, d []byte) uint32 {
	for _, b := range d {
		crc ^= uint32(b) << 16
		for i := 0; i < 8; i++ {
			crc <<= 1
			if crc&0x1000000 != 0 {
				crc ^= crc24Poly
			}
		}
예제 #15
0
파일: packet.go 프로젝트: marsch/camlistore
func parseSignatureSubpacket(sig *SignaturePacket, subpacket []byte, isHashed bool) (rest []byte, err os.Error) {
	// RFC 4880, section 5.2.3.1
	var length uint32
	switch {
	case subpacket[0] < 192:
		length = uint32(subpacket[0])
		subpacket = subpacket[1:]
	case subpacket[0] < 255:
		if len(subpacket) < 2 {
			goto Truncated
		}
		length = uint32(subpacket[0]-192)<<8 + uint32(subpacket[1]) + 192
		subpacket = subpacket[2:]
	default:
		if len(subpacket) < 5 {
			goto Truncated
		}
		length = uint32(subpacket[1])<<24 |
			uint32(subpacket[2])<<16 |
			uint32(subpacket[3])<<8 |
			uint32(subpacket[4])
		subpacket = subpacket[5:]
	}
	if length < uint32(len(subpacket)) {
		goto Truncated
	}
	rest = subpacket[length:]
	subpacket = subpacket[:length]
	if len(subpacket) == 0 {
		err = error.StructuralError("zero length signature subpacket")
		return
	}
	packetType := subpacket[0] & 0x7f
	isCritial := subpacket[0]&0x80 == 0x80
	subpacket = subpacket[1:]
	switch packetType {
	case 2:
		if !isHashed {
			err = error.StructuralError("signature creation time in non-hashed area")
			return
		}
		if len(subpacket) != 4 {
			err = error.StructuralError("signature creation time not four bytes")
			return
		}
		sig.CreationTime = uint32(subpacket[0])<<24 |
			uint32(subpacket[1])<<16 |
			uint32(subpacket[2])<<8 |
			uint32(subpacket[3])
	default:
		if isCritial {
			err = error.Unsupported("unknown critical signature subpacket")
			return
		}
	}
	return

Truncated:
	err = error.StructuralError("signature subpacket truncated")
	return
}
예제 #16
0
파일: armor.go 프로젝트: aubonbeurre/gcc
//    base64-encoded Bytes
//    '=' base64 encoded checksum
//    -----END Type-----
// where Headers is a possibly empty sequence of Key: Value lines.
//
// Since the armored data can be very large, this package presents a streaming
// interface.
type Block struct {
	Type    string            // The type, taken from the preamble (i.e. "PGP SIGNATURE").
	Header  map[string]string // Optional headers.
	Body    io.Reader         // A Reader from which the contents can be read
	lReader lineReader
	oReader openpgpReader
}

var ArmorCorrupt error = error_.StructuralError("armor invalid")

const crc24Init = 0xb704ce
const crc24Poly = 0x1864cfb
const crc24Mask = 0xffffff

// crc24 calculates the OpenPGP checksum as specified in RFC 4880, section 6.1
func crc24(crc uint32, d []byte) uint32 {
	for _, b := range d {
		crc ^= uint32(b) << 16
		for i := 0; i < 8; i++ {
			crc <<= 1
			if crc&0x1000000 != 0 {
				crc ^= crc24Poly
			}
		}