Example #1
0
func (vr *VerifyRequest) VerifySignature() bool {
	armorData := reArmor(vr.CamliSig)
	block, _ := armor.Decode(bytes.NewBufferString(armorData))
	if block == nil {
		return vr.fail("can't parse camliSig armor")
	}
	var p packet.Packet
	var err error
	p, err = packet.Read(block.Body)
	if err != nil {
		return vr.fail("error reading PGP packet from camliSig: " + err.Error())
	}
	sig, ok := p.(*packet.Signature)
	if !ok {
		return vr.fail("PGP packet isn't a signature packet")
	}
	if sig.Hash != crypto.SHA1 && sig.Hash != crypto.SHA256 {
		return vr.fail("I can only verify SHA1 or SHA256 signatures")
	}
	if sig.SigType != packet.SigTypeBinary {
		return vr.fail("I can only verify binary signatures")
	}
	hash := sig.Hash.New()
	hash.Write(vr.bp) // payload bytes
	err = vr.PublicKeyPacket.VerifySignature(hash, sig)
	if err != nil {
		return vr.fail(fmt.Sprintf("bad signature: %s", err))
	}
	vr.SignerKeyId = vr.PublicKeyPacket.KeyIdString()
	return true
}
Example #2
0
// CheckDetachedSignature takes a signed file and a detached signature and
// returns the signer if the signature is valid. If the signer isn't known,
// ErrUnknownIssuer is returned.
func CheckDetachedSignature(keyring KeyRing, signed, signature io.Reader) (signer *Entity, err error) {
	p, err := packet.Read(signature)
	if err != nil {
		return
	}

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

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

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

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

	_, err = io.Copy(wrappedHash, signed)
	if err != nil && err != io.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, errors.ErrUnknownIssuer
}
Example #3
0
func openArmoredPublicKeyFile(reader io.ReadCloser) (*packet.PublicKey, error) {
	defer reader.Close()

	var lr = io.LimitReader(reader, publicKeyMaxSize)
	block, _ := armor.Decode(lr)
	if block == nil {
		return nil, errors.New("Couldn't find PGP block in public key file")
	}
	if block.Type != "PGP PUBLIC KEY BLOCK" {
		return nil, errors.New("Invalid public key blob.")
	}
	p, err := packet.Read(block.Body)
	if err != nil {
		return nil, errors.New(fmt.Sprintf("Invalid public key blob: %v", err))
	}

	pk, ok := p.(*packet.PublicKey)
	if !ok {
		return nil, errors.New(fmt.Sprintf("Invalid public key blob; not a public key packet"))
	}
	return pk, nil
}
Example #4
0
// CheckDetachedSignature takes a signed file and a detached signature and
// returns the signer if the signature is valid. If the signer isn't known,
// ErrUnknownIssuer is returned.
func CheckDetachedSignature(keyring KeyRing, signed, signature io.Reader) (signer *Entity, err error) {
	p, err := packet.Read(signature)
	if err != nil {
		return
	}

	var issuerKeyId uint64
	var hashFunc crypto.Hash
	var sigType packet.SignatureType

	switch sig := p.(type) {
	case *packet.Signature:
		if sig.IssuerKeyId == nil {
			return nil, errors.StructuralError("signature doesn't have an issuer")
		}
		issuerKeyId = *sig.IssuerKeyId
		hashFunc = sig.Hash
		sigType = sig.SigType
	case *packet.SignatureV3:
		issuerKeyId = sig.IssuerKeyId
		hashFunc = sig.Hash
		sigType = sig.SigType
	default:
		return nil, errors.StructuralError("non signature packet found")
	}

	keys := keyring.KeysById(issuerKeyId)
	if len(keys) == 0 {
		return nil, errors.ErrUnknownIssuer
	}

	h, wrappedHash, err := hashForSignature(hashFunc, sigType)
	if err != nil {
		return
	}

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

	for _, key := range keys {
		if key.SelfSignature.FlagsValid && !key.SelfSignature.FlagSign {
			continue
		}
		switch sig := p.(type) {
		case *packet.Signature:
			err = key.PublicKey.VerifySignature(h, sig)
		case *packet.SignatureV3:
			err = key.PublicKey.VerifySignatureV3(h, sig)
		}
		if err == nil {
			return key.Entity, nil
		}
	}

	if err != nil {
		return
	}

	return nil, errors.ErrUnknownIssuer
}