Example #1
0
func (id ID) SHA1Hash() (ret ID) {
	var h hash.Hash
	h = sha1.New()
	h.Write(id.AsBytes())
	ret = FromBytes(h.Sum(nil))
	return ret
}
Example #2
0
// finishedSum30 calculates the contents of the verify_data member of a SSLv3
// Finished message given the MD5 and SHA1 hashes of a set of handshake
// messages.
func finishedSum30(md5, sha1 hash.Hash, masterSecret []byte, magic []byte) []byte {
	md5.Write(magic)
	md5.Write(masterSecret)
	md5.Write(ssl30Pad1[:])
	md5Digest := md5.Sum(nil)

	md5.Reset()
	md5.Write(masterSecret)
	md5.Write(ssl30Pad2[:])
	md5.Write(md5Digest)
	md5Digest = md5.Sum(nil)

	sha1.Write(magic)
	sha1.Write(masterSecret)
	sha1.Write(ssl30Pad1[:40])
	sha1Digest := sha1.Sum(nil)

	sha1.Reset()
	sha1.Write(masterSecret)
	sha1.Write(ssl30Pad2[:40])
	sha1.Write(sha1Digest)
	sha1Digest = sha1.Sum(nil)

	ret := make([]byte, len(md5Digest)+len(sha1Digest))
	copy(ret, md5Digest)
	copy(ret[len(md5Digest):], sha1Digest)
	return ret
}
Example #3
0
func passwordToKey(proto AuthProtocol, password string, engineId []byte) []byte {
	var h hash.Hash
	switch proto {
	case Md5:
		h = md5.New()
	case Sha:
		h = sha1.New()
	}

	pass := []byte(password)
	plen := len(pass)
	for i := mega / plen; i > 0; i-- {
		h.Write(pass)
	}
	remain := mega % plen
	if remain > 0 {
		h.Write(pass[:remain])
	}
	ku := h.Sum(nil)

	h.Reset()
	h.Write(ku)
	h.Write(engineId)
	h.Write(ku)
	return h.Sum(nil)
}
Example #4
0
// Checksum returns the checksum of some data, using a specified algorithm.
// It only returns an error when an invalid algorithm is used. The valid ones
// are MD5, SHA1, SHA224, SHA256, SHA384, SHA512, SHA3224, SHA3256, SHA3384,
// and SHA3512.
func Checksum(algorithm string, data []byte) (checksum string, err error) {
	// default
	var hasher hash.Hash
	switch strings.ToUpper(algorithm) {
	case "MD5":
		hasher = md5.New()
	case "SHA1":
		hasher = sha1.New()
	case "SHA224":
		hasher = sha256.New224()
	case "SHA256":
		hasher = sha256.New()
	case "SHA384":
		hasher = sha512.New384()
	case "SHA512":
		hasher = sha512.New()
	case "SHA3224":
		hasher = sha3.New224()
	case "SHA3256":
		hasher = sha3.New256()
	case "SHA3384":
		hasher = sha3.New384()
	case "SHA3512":
		hasher = sha3.New512()
	default:
		msg := "Invalid algorithm parameter passed go Checksum: %s"
		return checksum, fmt.Errorf(msg, algorithm)
	}
	hasher.Write(data)
	str := hex.EncodeToString(hasher.Sum(nil))
	return str, nil
}
Example #5
0
func authenticateMessage(signers map[string]Signer, header *Header,
	pack *PipelinePack) bool {
	digest := header.GetHmac()
	if digest != nil {
		var key string
		signer := fmt.Sprintf("%s_%d", header.GetHmacSigner(),
			header.GetHmacKeyVersion())
		if s, ok := signers[signer]; ok {
			key = s.HmacKey
		} else {
			return false
		}

		var hm hash.Hash
		switch header.GetHmacHashFunction() {
		case Header_MD5:
			hm = hmac.New(md5.New, []byte(key))
		case Header_SHA1:
			hm = hmac.New(sha1.New, []byte(key))
		}
		hm.Write(pack.MsgBytes)
		expectedDigest := hm.Sum(nil)
		if bytes.Compare(digest, expectedDigest) != 0 {
			return false
		}
		pack.Signer = header.GetHmacSigner()
	}
	return true
}
Example #6
0
func generateChecksum(h hash.Hash, b *[]byte) string {
	_, err := h.Write(*b)
	if err != nil {
		return ""
	}
	return fmt.Sprintf("%x", h.Sum(nil))
}
//TODO: test and add to tests
//RIPEMD-160 operation for bitcoin address hashing
func Ripemd(b []byte) []byte {
	//ripemd hashing of the sha hash
	var h hash.Hash = ripemd160.New()
	h.Write(b)

	return h.Sum(nil) //return
}
Example #8
0
// Return the fingerprint of the key in a raw format.
func Fingerprint(pub *SSHPublicKey, hashalgo crypto.Hash) (fpr []byte, err error) {
	var h hash.Hash

	// The default algorithm for OpenSSH appears to be MD5.
	if hashalgo == 0 {
		hashalgo = crypto.MD5
	}

	switch hashalgo {
	case crypto.MD5:
		h = md5.New()
	case crypto.SHA1:
		h = sha1.New()
	case crypto.SHA256:
		h = sha256.New()
	default:
		return nil, ErrInvalidDigest
	}

	blob, err := publicToBlob(pub)
	if err != nil {
		return nil, err
	}
	h.Write(blob)

	return h.Sum(nil), nil
}
Example #9
0
// Send len(data) # of sequential packets, hashed with the provided hash.Hash
// down the provided channel
func sequentialPacketChannel(data []byte, hasher hash.Hash) chan *Packet {
	// FIXME: Packet size is hard-coded at 1
	outchan := make(chan *Packet)
	go func() {
		for i, _ := range data {
			var mbuf [64]byte

			hasher.Write(data[i : i+1])
			m := hasher.Sum(nil)
			for i, _ := range mbuf {
				mbuf[i] = m[i]
			}
			hasher.Reset()

			h := PacketHeader{
				SequenceN: uint32(i),
				Mac:       mbuf,
				Size:      uint32(1),
			}
			outchan <- &Packet{h, data[i : i+1]}
		}

		close(outchan)
	}()

	return outchan
}
Example #10
0
// verifyChecksum computes the hash of a file and compares it
// to a checksum. If comparison fails, it returns an error.
func verifyChecksum(fd *os.File, checksum string) (err error) {
	defer func() {
		if e := recover(); e != nil {
			err = fmt.Errorf("verifyChecksum() -> %v", e)
		}
	}()
	var h hash.Hash
	h = sha256.New()
	buf := make([]byte, 4096)
	var offset int64 = 0
	for {
		block, err := fd.ReadAt(buf, offset)
		if err != nil && err != io.EOF {
			panic(err)
		}
		if block == 0 {
			break
		}
		h.Write(buf[:block])
		offset += int64(block)
	}
	hexhash := fmt.Sprintf("%x", h.Sum(nil))
	if hexhash != checksum {
		return fmt.Errorf("Checksum validation failed. Got '%s', Expected '%s'.",
			hexhash, checksum)
	}
	return
}
Example #11
0
// Returns UUID based on hashing of namespace UUID and name.
func newFromHash(h hash.Hash, ns UUID, name string) UUID {
	u := UUID{}
	h.Write(ns[:])
	h.Write([]byte(name))
	copy(u[:], h.Sum(nil))
	return u
}
Example #12
0
func (otp *OTP) hashCalc(algorithm string) ([8]byte, error) {
	var hash_algorithm hash.Hash

	tmpseq := STAITC_OTP_OTP_REP_COUNT - (otp.seq % STAITC_OTP_OTP_REP_COUNT)
	_string_ := strconv.Itoa(otp.seed) + otp.passphrase

	switch otp.mAlgorithm {
	case "MD4":
		hash_algorithm = md4.New()
	case "MD5":
		hash_algorithm = md5.New()
	case "RIPEMD128":
		hash_algorithm = ripemd128.New()
	case "RIPEMD160":
		hash_algorithm = ripemd160.New()
	case "SHA1":
		hash_algorithm = sha1.New()
	default:
		return [8]byte{0, 0, 0, 0, 0, 0, 0, 0}, fmt.Errorf("NoSuchAlgorithmException: %s", otp.mAlgorithm)
	}

	hash_algorithm.Reset()
	hash_algorithm.Write(UCS2_to_UTF8([]byte(_string_)))
	otp.hash = hashValueTo8(hash_algorithm.Sum(nil))

	for tmpseq > 0 {
		hash_algorithm.Reset()
		hash_algorithm.Write(otp.hash[:])
		otp.hash = hashValueTo8(hash_algorithm.Sum(nil))
		tmpseq--
	}

	return otp.hash, nil
}
Example #13
0
// CheckMAC returns true if messageMAC is a valid HMAC tag for message.
func CheckMAC(message []byte, messageMAC string, key string) bool {
	var err error
	var mac hash.Hash
	var macdata []byte
	var macparts = strings.Split(messageMAC, "=")
	macdata, err = hex.DecodeString(macparts[1])
	if err != nil {
		log.Print("Error decoding hex digest: ", err)
		return false
	}
	switch macparts[0] {
	case "md5":
		mac = hmac.New(md5.New, []byte(key))
	case "sha1":
		mac = hmac.New(sha1.New, []byte(key))
	case "sha256":
		mac = hmac.New(sha256.New, []byte(key))
	case "sha512":
		mac = hmac.New(sha512.New, []byte(key))
	default:
		log.Print("Unsupported hash: ", macparts[0])
		return false
	}
	mac.Write(message)
	expectedMAC := mac.Sum(nil)
	return hmac.Equal(macdata, expectedMAC)
}
Example #14
0
// VerifySignature returns nil iff sig is a valid signature, made by this
// public key, of the data hashed into signed. signed is mutated by this call.
func (pk *PublicKey) VerifySignature(signed hash.Hash, sig *Signature) (err error) {
	if !pk.CanSign() {
		return errors.InvalidArgumentError("public key cannot generate signatures")
	}

	signed.Write(sig.HashSuffix)
	hashBytes := signed.Sum(nil)

	// NOTE(maxtaco) 2016-08-22
	//
	// We used to do this:
	//
	// if hashBytes[0] != sig.HashTag[0] || hashBytes[1] != sig.HashTag[1] {
	//	  return errors.SignatureError("hash tag doesn't match")
	// }
	//
	// But don't do anything in this case. Some GPGs generate bad
	// 2-byte hash prefixes, but GPG also doesn't seem to care on
	// import. See BrentMaxwell's key. I think it's safe to disable
	// this check!

	if pk.PubKeyAlgo != sig.PubKeyAlgo {
		return errors.InvalidArgumentError("public key and signature use different algorithms")
	}

	switch pk.PubKeyAlgo {
	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
		rsaPublicKey, _ := pk.PublicKey.(*rsa.PublicKey)
		err = rsa.VerifyPKCS1v15(rsaPublicKey, sig.Hash, hashBytes, sig.RSASignature.bytes)
		if err != nil {
			return errors.SignatureError("RSA verification failure")
		}
		return nil
	case PubKeyAlgoDSA:
		dsaPublicKey, _ := pk.PublicKey.(*dsa.PublicKey)
		// Need to truncate hashBytes to match FIPS 186-3 section 4.6.
		subgroupSize := (dsaPublicKey.Q.BitLen() + 7) / 8
		if len(hashBytes) > subgroupSize {
			hashBytes = hashBytes[:subgroupSize]
		}
		if !dsa.Verify(dsaPublicKey, hashBytes, new(big.Int).SetBytes(sig.DSASigR.bytes), new(big.Int).SetBytes(sig.DSASigS.bytes)) {
			return errors.SignatureError("DSA verification failure")
		}
		return nil
	case PubKeyAlgoECDSA:
		ecdsaPublicKey := pk.PublicKey.(*ecdsa.PublicKey)
		if !ecdsa.Verify(ecdsaPublicKey, hashBytes, new(big.Int).SetBytes(sig.ECDSASigR.bytes), new(big.Int).SetBytes(sig.ECDSASigS.bytes)) {
			return errors.SignatureError("ECDSA verification failure")
		}
		return nil
	case PubKeyAlgoEdDSA:
		if !pk.edk.Verify(hashBytes, sig.EdDSASigR, sig.EdDSASigS) {
			return errors.SignatureError("EdDSA verification failure")
		}
		return nil
	default:
		return errors.SignatureError("Unsupported public key algorithm used in signature")
	}
	panic("unreachable")
}
Example #15
0
// MakeSignature returns a auth_v4 signature from the `string to sign` variable.
// May be useful for creating v4 requests for services other than DynamoDB.
func MakeSignature(string2sign, zone, service, secret string) string {
	kCredentials, _ := cacheable_hmacs(zone, service, secret)
	var kSigning_hmac_sha256 hash.Hash = hmac.New(sha256.New, kCredentials)
	kSigning_hmac_sha256.Write([]byte(string2sign))
	kSigning := kSigning_hmac_sha256.Sum(nil)
	return hex.EncodeToString(kSigning)
}
Example #16
0
func BufSHA256(buf []byte) string {
	var h hash.Hash = sha256.New()
	h.Write(buf[:])
	digest := h.Sum(nil)
	//fmt.Printf("%s digest ->%s\n",fname,rv)
	return DigestToString(digest)
}
Example #17
0
// VerifySignature returns nil iff sig is a valid signature, made by this
// public key, of the data hashed into signed. signed is mutated by this call.
func (pk *PublicKey) VerifySignature(signed hash.Hash, sig *Signature) (err os.Error) {
	if !pk.CanSign() {
		return error.InvalidArgumentError("public key cannot generate signatures")
	}

	signed.Write(sig.HashSuffix)
	hashBytes := signed.Sum()

	if hashBytes[0] != sig.HashTag[0] || hashBytes[1] != sig.HashTag[1] {
		return error.SignatureError("hash tag doesn't match")
	}

	if pk.PubKeyAlgo != sig.PubKeyAlgo {
		return error.InvalidArgumentError("public key and signature use different algorithms")
	}

	switch pk.PubKeyAlgo {
	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
		rsaPublicKey, _ := pk.PublicKey.(*rsa.PublicKey)
		err = rsa.VerifyPKCS1v15(rsaPublicKey, sig.Hash, hashBytes, sig.RSASignature)
		if err != nil {
			return error.SignatureError("RSA verification failure")
		}
		return nil
	case PubKeyAlgoDSA:
		dsaPublicKey, _ := pk.PublicKey.(*dsa.PublicKey)
		if !dsa.Verify(dsaPublicKey, hashBytes, sig.DSASigR, sig.DSASigS) {
			return error.SignatureError("DSA verification failure")
		}
		return nil
	default:
		panic("shouldn't happen")
	}
	panic("unreachable")
}
Example #18
0
// Compute md5 for given file
// Test is Test_005
func FileMD5(fname string) (string, error) {
	//fmt.Printf("Computing digest for %s\n",fname)
	const NBUF = 1 << 20 // 20 -> 1 MB
	file, err := os.OpenFile(fname, os.O_RDONLY, 0666)
	if file == nil {
		fmt.Printf("!Err--> mdr.FileMD5() can't open file %s as readonly; err=%v\n", fname, err)
		return "", err
	}
	defer file.Close()
	buf := make([]byte, NBUF)
	var h hash.Hash = md5.New()
	for {
		numRead, err := file.Read(buf)
		if (err == io.EOF) && (numRead == 0) {
			break
		} // end of file reached
		if (err != nil) || (numRead < 0) {
			fmt.Fprintf(os.Stderr, "!Err--> mdr.FileMD5: error reading from %s: %v\n", fname, err)
			return "", err
		}
		//		fmt.Printf("read(%d) bytes\n",numRead)
		h.Write(buf[0:numRead])
	}
	digest := h.Sum(nil)
	rv := DigestToString(digest)
	//fmt.Printf("%s digest ->%s\n",fname,rv)
	return string(rv), nil
}
Example #19
0
// NIST SP 800-56 Concatenation Key Derivation Function (see section 5.8.1).
func concatKDF(hash hash.Hash, z, s1 []byte, kdLen int) (k []byte, err error) {
	if s1 == nil {
		s1 = make([]byte, 0)
	}

	reps := ((kdLen + 7) * 8) / (hash.BlockSize() * 8)
	if big.NewInt(int64(reps)).Cmp(big2To32M1) > 0 {
		fmt.Println(big2To32M1)
		return nil, ErrKeyDataTooLong
	}

	counter := []byte{0, 0, 0, 1}
	k = make([]byte, 0)

	for i := 0; i <= reps; i++ {
		hash.Write(counter)
		hash.Write(z)
		hash.Write(s1)
		k = append(k, hash.Sum(nil)...)
		hash.Reset()
		incCounter(counter)
	}

	k = k[:kdLen]
	return
}
Example #20
0
func checkMAC(mac hash.Hash, message, messageMAC []byte) bool {
	if _, err := mac.Write(message); err != nil {
		return false
	}
	expectedMAC := mac.Sum(nil)
	return hmac.Equal(messageMAC, expectedMAC)
}
Example #21
0
func (s *S) TestSendMessageWithAttributes(c *C) {
	testServer.PrepareResponse(200, nil, TestSendMessageXmlOK)

	q := &Queue{s.sqs, testServer.URL + "/123456789012/testQueue/"}
	attrs := map[string]string{
		"test_attribute_name_1": "test_attribute_value_1",
	}
	resp, err := q.SendMessageWithAttributes("This is a test message", attrs)
	req := testServer.WaitRequest()

	c.Assert(req.Method, Equals, "GET")
	c.Assert(req.URL.Path, Equals, "/123456789012/testQueue/")
	c.Assert(req.Header["Date"], Not(Equals), "")

	var attrsHash = md5.New()
	attrsHash.Write(encodeMessageAttribute("test_attribute_name_1"))
	attrsHash.Write(encodeMessageAttribute("String"))
	attrsHash.Write([]byte{1})
	attrsHash.Write(encodeMessageAttribute("test_attribute_value_1"))
	c.Assert(resp.MD5OfMessageAttributes, Equals, fmt.Sprintf("%x", attrsHash.Sum(nil)))

	msg := "This is a test message"
	var h hash.Hash = md5.New()
	h.Write([]byte(msg))
	c.Assert(resp.MD5, Equals, fmt.Sprintf("%x", h.Sum(nil)))
	c.Assert(resp.Id, Equals, "5fea7756-0ea4-451a-a703-a558b933e274")
	c.Assert(err, IsNil)
}
Example #22
0
func calculateRef(h hash.Hash, data []byte) *Ref {
	var tmp [RefLen]byte
	h.Reset()
	h.Write(data)
	mac := h.Sum(tmp[:0])
	return RefFromBytes(mac)
}
Example #23
0
// Returns true if the provided message is unsigned or has a valid signature
// from one of the provided signers.
func authenticateMessage(signers map[string]Signer, header *Header, msg []byte) bool {
	digest := header.GetHmac()
	if digest != nil {
		var key string
		signer := fmt.Sprintf("%s_%d", header.GetHmacSigner(),
			header.GetHmacKeyVersion())
		if s, ok := signers[signer]; ok {
			key = s.HmacKey
		} else {
			return false
		}

		var hm hash.Hash
		switch header.GetHmacHashFunction() {
		case Header_MD5:
			hm = hmac.New(md5.New, []byte(key))
		case Header_SHA1:
			hm = hmac.New(sha1.New, []byte(key))
		}
		hm.Write(msg)
		expectedDigest := hm.Sum(nil)
		if subtle.ConstantTimeCompare(digest, expectedDigest) != 1 {
			return false
		}
	}
	return true
}
Example #24
0
func TestKeccak(t *testing.T) {
	for i := range tests {
		var h hash.Hash

		switch tests[i].length {
		case 28:
			h = New224()
		case 32:
			h = New256()
		case 48:
			h = New384()
		case 64:
			h = New512()
		default:
			panic("invalid testcase")
		}

		h.Write(tests[i].input)

		d := h.Sum(nil)
		if !bytes.Equal(d, tests[i].output) {
			t.Errorf("testcase %d: expected %x got %x", i, tests[i].output, d)
		}
	}
}
Example #25
0
func LoadPost(ctx *web.Context, val string) {
	username := ctx.Params["username"]
	password := ctx.Params["password"]

	salt := strconv.Itoa64(time.Nanoseconds()) + username

	var h hash.Hash = sha256.New()
	h.Write([]byte(password + salt))

	s, _err := conn.Prepare("INSERT INTO users VALUES(NULL, ?, ?, ?)")
	utils.ReportErr(_err)

	s.Exec(username, string(h.Sum()), salt)
	s.Finalize()
	conn.Close()
	sidebar := utils.Loadmustache("admin.mustache", &map[string]string{})

	//TESTING, REMOVE LATER
	script := "<script type=\"text/javascript\" src=\"../inc/adminref.js\"></script>"
	content := "Welcome to the admin panel, use the control box on your right to control the site content"
	//ENDTESTING

	mapping := map[string]string{"css": "../inc/site.css",
		"title":   "Proggin: Admin panel",
		"sidebar": sidebar,
		"content": content,
		"script":  script}

	output := utils.Loadmustache("frame.mustache", &mapping)
	ctx.WriteString(output)
}
Example #26
0
// Tweak generates a new tweak from the mode, hash, salt length (in
// bytes), and any additional data. It provides additional information
// that will complicate an attacker's efforts, and allows a system to
// differentiate between different uses of the Catena function's output.
func Tweak(mode byte, H hash.Hash, saltLen int, ad []byte) ([]byte, error) {
	if mode != ModePassHash && mode != ModeKeyDerivation {
		return nil, ErrInvalidTweakMode
	}

	hashLen := H.Size()
	tweakLen := 5 + hashLen
	var t = make([]byte, 1, tweakLen)
	t[0] = mode

	var tmp uint16 = uint16(H.Size() * 8)
	high := byte(tmp >> 8)
	low := byte(tmp << 8 >> 8)
	t = append(t, high)
	t = append(t, low)

	tmp = uint16(saltLen * 8)
	high = byte(tmp >> 8)
	low = byte(tmp << 8 >> 8)
	t = append(t, high)
	t = append(t, low)

	H.Reset()
	H.Write(ad)
	t = append(t, H.Sum(nil)...)
	H.Reset()
	return t, nil
}
Example #27
0
// writeEncodedData -
func (b bucket) writeEncodedData(k, m uint8, writers []io.WriteCloser, objectData io.Reader, sumMD5, sum512 hash.Hash) (int, int, error) {
	chunks := split.Stream(objectData, 10*1024*1024)
	encoder, err := newEncoder(k, m, "Cauchy")
	if err != nil {
		return 0, 0, iodine.New(err, nil)
	}
	chunkCount := 0
	totalLength := 0
	for chunk := range chunks {
		if chunk.Err == nil {
			totalLength = totalLength + len(chunk.Data)
			encodedBlocks, _ := encoder.Encode(chunk.Data)
			sumMD5.Write(chunk.Data)
			sum512.Write(chunk.Data)
			for blockIndex, block := range encodedBlocks {
				_, err := io.Copy(writers[blockIndex], bytes.NewBuffer(block))
				if err != nil {
					return 0, 0, iodine.New(err, nil)
				}
			}
		}
		chunkCount = chunkCount + 1
	}
	return chunkCount, totalLength, nil
}
Example #28
0
// DeriveConcatKDF implements NIST SP 800-56A Concatenation Key Derivation Function. Derives
// key material of keydatalen bits size given Z (sharedSecret), OtherInfo (AlgorithmID |
// PartyUInfo | PartyVInfo | SuppPubInfo | SuppPrivInfo) and hash function
func DeriveConcatKDF(keydatalen int, sharedSecret, algId, partyUInfo, partyVInfo, suppPubInfo, suppPrivInfo []byte, h hash.Hash) []byte {

	otherInfo := arrays.Concat(algId, partyUInfo, partyVInfo, suppPubInfo, suppPrivInfo)

	keyLenBytes := keydatalen >> 3

	reps := int(math.Ceil(float64(keyLenBytes) / float64(h.Size())))

	if reps > MaxInt {
		panic("kdf.DeriveConcatKDF: too much iterations (more than 2^32-1).")
	}

	dk := make([]byte, 0, keyLenBytes)

	for counter := 1; counter <= reps; counter++ {
		h.Reset()

		counterBytes := arrays.UInt32ToBytes(uint32(counter))

		h.Write(counterBytes)
		h.Write(sharedSecret)
		h.Write(otherInfo)

		dk = h.Sum(dk)
	}

	return dk[:keyLenBytes]
}
// VerifySignatureV3 returns nil iff sig is a valid signature, made by this
// public key, of the data hashed into signed. signed is mutated by this call.
func (pk *PublicKeyV3) VerifySignatureV3(signed hash.Hash, sig *SignatureV3) (err error) {
	if !pk.CanSign() {
		return errors.InvalidArgumentError("public key cannot generate signatures")
	}

	suffix := make([]byte, 5)
	suffix[0] = byte(sig.SigType)
	binary.BigEndian.PutUint32(suffix[1:], uint32(sig.CreationTime.Unix()))
	signed.Write(suffix)
	hashBytes := signed.Sum(nil)

	if hashBytes[0] != sig.HashTag[0] || hashBytes[1] != sig.HashTag[1] {
		return errors.SignatureError("hash tag doesn't match")
	}

	if pk.PubKeyAlgo != sig.PubKeyAlgo {
		return errors.InvalidArgumentError("public key and signature use different algorithms")
	}

	switch pk.PubKeyAlgo {
	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
		if err = rsa.VerifyPKCS1v15(pk.PublicKey, sig.Hash, hashBytes, sig.RSASignature.bytes); err != nil {
			return errors.SignatureError("RSA verification failure")
		}
		return
	default:
		// V3 public keys only support RSA.
		panic("shouldn't happen")
	}
	panic("unreachable")
}
Example #30
0
// concat key derivation function
//  See: 5.8.1 of NIST.800-56A
func concatKDF(masterKey []byte, keyType string, encKeySize, macKeySize int) ([]byte, []byte) {

	// build buffer common to encryption and integrity derivation
	buffer := make([]byte, len(masterKey)+len(keyType)+26)
	binary.BigEndian.PutUint32(buffer[:], uint32(1))
	copy(buffer[4:], masterKey)
	copy(buffer[8+len(masterKey):], keyType)
	binary.BigEndian.PutUint32(buffer[8+len(masterKey)+len(keyType):], uint32(0))
	binary.BigEndian.PutUint32(buffer[12+len(masterKey)+len(keyType):], uint32(0))

	// derive the encryption key
	binary.BigEndian.PutUint32(buffer[4+len(masterKey):], uint32(encKeySize))
	copy(buffer[16+len(masterKey)+len(keyType):], "Encryption")

	var h hash.Hash
	if macKeySize == 256 {
		h = sha256.New()
	} else if macKeySize == 512 {
		h = sha512.New()
	} else {
		panic("Unknown hash size")
	}
	h.Write(buffer)
	encKey := h.Sum(nil)

	// derive the integrity key
	binary.BigEndian.PutUint32(buffer[4+len(masterKey):], uint32(macKeySize))
	copy(buffer[16+len(masterKey)+len(keyType):], "Integrity")

	h.Reset()
	h.Write(buffer[:len(buffer)-1])
	macKey := h.Sum(nil)

	return encKey[:encKeySize/8], macKey[:macKeySize/8]
}