Copyright 2013 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.

package packet

import (
	
	
	
	
	
	

	
	
)
SignatureV3 represents older version 3 signatures. These signatures are less secure than version 4 and should not be used to create new signatures. They are included here for backwards compatibility to read and validate with older key material. See RFC 4880, section 5.2.2.
RFC 4880, section 5.2.2
	var  [8]byte
	if _,  = readFull(, [:1]);  != nil {
		return
	}
	if [0] < 2 || [0] > 3 {
		 = errors.UnsupportedError("signature packet version " + strconv.Itoa(int([0])))
		return
	}
	if _,  = readFull(, [:1]);  != nil {
		return
	}
	if [0] != 5 {
		 = errors.UnsupportedError(
			"invalid hashed material length " + strconv.Itoa(int([0])))
		return
	}
Read hashed material: signature type + creation time
	if _,  = readFull(, [:5]);  != nil {
		return
	}
	.SigType = SignatureType([0])
	 := binary.BigEndian.Uint32([1:5])
	.CreationTime = time.Unix(int64(), 0)
Eight-octet Key ID of signer.
	if _,  = readFull(, [:8]);  != nil {
		return
	}
	.IssuerKeyId = binary.BigEndian.Uint64([:])
Public-key and hash algorithm
	if _,  = readFull(, [:2]);  != nil {
		return
	}
	.PubKeyAlgo = PublicKeyAlgorithm([0])
	switch .PubKeyAlgo {
	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly, PubKeyAlgoDSA:
	default:
		 = errors.UnsupportedError("public key algorithm " + strconv.Itoa(int(.PubKeyAlgo)))
		return
	}
	var  bool
	if .Hash,  = s2k.HashIdToHash([1]); ! {
		return errors.UnsupportedError("hash function " + strconv.Itoa(int([2])))
	}
Two-octet field holding left 16 bits of signed hash value.
	if _,  = readFull(, .HashTag[:2]);  != nil {
		return
	}

	switch .PubKeyAlgo {
	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
		.RSASignature.bytes, .RSASignature.bitLength,  = readMPI()
	case PubKeyAlgoDSA:
		if .DSASigR.bytes, .DSASigR.bitLength,  = readMPI();  != nil {
			return
		}
		.DSASigS.bytes, .DSASigS.bitLength,  = readMPI()
	default:
		panic("unreachable")
	}
	return
}
Serialize marshals sig to w. Sign, SignUserId or SignKey must have been called first.
func ( *SignatureV3) ( io.Writer) ( error) {
	 := make([]byte, 8)
Write the sig type and creation time
	[0] = byte(.SigType)
	binary.BigEndian.PutUint32([1:5], uint32(.CreationTime.Unix()))
	if _,  = .Write([:5]);  != nil {
		return
	}
Write the issuer long key ID
	binary.BigEndian.PutUint64([:8], .IssuerKeyId)
	if _,  = .Write([:8]);  != nil {
		return
	}
Write public key algorithm, hash ID, and hash value
	[0] = byte(.PubKeyAlgo)
	,  := s2k.HashToHashId(.Hash)
	if ! {
		return errors.UnsupportedError(fmt.Sprintf("hash function %v", .Hash))
	}
	[1] = 
	copy([2:4], .HashTag[:])
	if _,  = .Write([:4]);  != nil {
		return
	}

	if .RSASignature.bytes == nil && .DSASigR.bytes == nil {
		return errors.InvalidArgumentError("Signature: need to call Sign, SignUserId or SignKey before Serialize")
	}

	switch .PubKeyAlgo {
	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
		 = writeMPIs(, .RSASignature)
	case PubKeyAlgoDSA:
		 = writeMPIs(, .DSASigR, .DSASigS)
	default:
		panic("impossible")
	}
	return