Пример #1
0
func (hashStruct *Pbkdf2Hash) UnmarshalJSON(input []byte) error {
	var t struct {
		Hash       string
		Salt       string
		Iterations uint16
	}

	dec := json.NewDecoder(bytes.NewReader(input))
	if e := dec.Decode(&t); e != nil {
		return e
	} else if h, e := base64.StdEncoding.DecodeString(t.Hash); e != nil {
		return e
	} else if len(h) != Pbkdf2KeyLength {
		return IncorrectHashLengthError
	} else if s, e := base64.StdEncoding.DecodeString(t.Salt); e != nil {
		return e
	} else if len(s) != Pbkdf2KeyLength {
		return IncorrectSaltLengthError
	} else if t.Iterations < Pbkdf2MinIterations {
		return InsufficientIterationsError
	} else {
		subtle.ConstantTimeCopy(1, hashStruct.Hash[:], h)
		subtle.ConstantTimeCopy(1, hashStruct.Salt[:], s)
		hashStruct.Iterations = t.Iterations
		return nil
	}
}
Пример #2
0
func (s *Server) AuthHandler() http.Handler {
	handler := func(w http.ResponseWriter, r *http.Request) {
		/*
			Parse form data and handle error messages. Might not be the most visible to the end user.
		*/
		err := r.ParseForm()
		if err != nil {
			fmt.Println(err)
			return
		}

		message := r.FormValue("message")
		signature := r.FormValue("signature")
		publicKey := r.FormValue("publicKey")

		/*
			Decode publicKey and signature to a byte array using base64url package
		*/
		pubBytes, pubErr := base64url.Decode(publicKey)
		if pubErr != nil {
			fmt.Println(pubErr)
		}
		signBytes, signErr := base64url.Decode(signature)
		if signErr != nil {
			fmt.Println(signErr)
		}

		/*
			Change the byte array to an object with the correct sizes used by the ed25519 implementation
		*/
		var pk *[ed25519.PublicKeySize]byte
		pk = new([ed25519.PublicKeySize]byte)
		subtle.ConstantTimeCopy(1, pk[:32], pubBytes)
		var sig *[ed25519.SignatureSize]byte
		sig = new([ed25519.SignatureSize]byte)
		subtle.ConstantTimeCopy(1, sig[:64], signBytes)

		/*
			Verify the signature and return verified or not depending on the result.
		*/
		w.Header().Add("Content-Type", "text/html")
		if ed25519.Verify(pk, []byte(message), sig) {
			io.WriteString(w, "{result:true}Verified")
		} else {
			io.WriteString(w, "{result:false}Not Verified")
		}
	}
	return http.HandlerFunc(handler)
}
Пример #3
0
// SetPassword is a function that allows a password to be hashed and added to
// an InMemPwdStore instance.
func GetPbkdf2Hash(
	password string,
	iterations uint16,
) (*Pbkdf2Hash, error) {
	if iterations < Pbkdf2MinIterations {
		return nil, InsufficientIterationsError
	}

	var hashStruct Pbkdf2Hash
	randCount, err := rand.Read(hashStruct.Salt[:])
	if err != nil {
		return nil, err
	} else if randCount != Pbkdf2KeyLength {
		return nil, InsufficientEntropyError
	}

	hashStruct.Iterations = iterations

	subtle.ConstantTimeCopy(1, hashStruct.Hash[:], pbkdf2.Key(
		[]byte(password),
		hashStruct.Salt[:],
		int(hashStruct.Iterations),
		Pbkdf2KeyLength,
		sha256.New,
	))

	return &hashStruct, nil
}
Пример #4
0
// Decrypt implements the crypto.Decrypter operation for the given key.
func (key *PrivateKey) Decrypt(rand io.Reader, msg []byte, opts crypto.DecrypterOpts) ([]byte, error) {
	switch opts := opts.(type) {
	case *rsa.PKCS1v15DecryptOptions:
		ptxt, decyptErr := key.execute(gokeyless.OpRSADecrypt, msg)

		// If opts.SessionKeyLen is set, we must perform a variation of
		// rsa.DecryptPKCS1v15SessionKey to ensure the entire operation
		// is performed in constant time regardless of padding errors.
		if l := opts.SessionKeyLen; l > 0 {
			plaintext := make([]byte, l)
			if _, err := io.ReadFull(rand, plaintext); err != nil {
				return nil, err
			}
			valid := subtle.ConstantTimeEq(int32(len(ptxt)), int32(l))
			v2 := subtle.ConstantTimeLessOrEq(l, len(ptxt))
			l2 := subtle.ConstantTimeSelect(v2, l, len(ptxt))
			subtle.ConstantTimeCopy(valid, plaintext[:l2], ptxt[:l2])
			return plaintext, nil
		}
		// Otherwise, we can just return the error like rsa.DecryptPKCS1v15.
		return ptxt, decyptErr
	default:
		return nil, errors.New("invalid options for Decrypt")
	}
}
Пример #5
0
// Decrypt implements the crypto.Decrypter operation for the given key.
func (key *PrivateKey) Decrypt(rand io.Reader, msg []byte, opts crypto.DecrypterOpts) ([]byte, error) {
	opts1v15, ok := opts.(*rsa.PKCS1v15DecryptOptions)
	if opts != nil && !ok {
		return nil, errors.New("invalid options for Decrypt")
	}

	ptxt, err := key.execute(gokeyless.OpRSADecrypt, msg)
	if err != nil {
		return nil, err
	}

	if ok {
		// If opts.SessionKeyLen is set, we must perform a variation of
		// rsa.DecryptPKCS1v15SessionKey to ensure the entire operation
		// is performed in constant time regardless of padding errors.
		if l := opts1v15.SessionKeyLen; l > 0 {
			plaintext := make([]byte, l)
			if _, err := io.ReadFull(rand, plaintext); err != nil {
				return nil, err
			}
			valid := subtle.ConstantTimeEq(int32(len(ptxt)), int32(l))
			v2 := subtle.ConstantTimeLessOrEq(l, len(ptxt))
			l2 := subtle.ConstantTimeSelect(v2, l, len(ptxt))
			subtle.ConstantTimeCopy(valid, plaintext[:l2], ptxt[:l2])
			return plaintext, nil
		}
	}
	return ptxt, nil
}
Пример #6
0
// Verify returns true if the cryptographic signature sig.
func (k *Key) Verify(msg []byte, sig *Signature) bool {
	var pk *[ed25519.PublicKeySize]byte
	subtle.ConstantTimeCopy(1, pk[:32], k[:])
	// pk := [ed25519.PublicKeySize]byte(*k)
	s := [ed25519.SignatureSize]byte(*sig)
	return ed25519.Verify(pk, msg, &s)
}
Пример #7
0
// DomainKey returns the private key for domain.
// HMAC-SHA256 using k as the key and domain as the message to generate the 256-bit private key.
func (k *Key) DomainKey(domain string) (key *Key) {
	mac := hmac.New(sha256.New, k[:])
	mac.Write([]byte(domain))
	bytes := mac.Sum(nil)
	subtle.ConstantTimeCopy(1, key[:keyLen], bytes[:keyLen])
	return
}
Пример #8
0
//TODO test MakePassword
func MakePassword(pass []byte) []byte {
	salt := make([]byte, SaltSize)
	_, err := rand.Read(salt)
	if err != nil {
		return nil
	}

	key := HashPassword(pass, salt)
	if key == nil {
		return nil
	}
	hashed := make([]byte, KeySize+SaltSize)
	subtle.ConstantTimeCopy(1, hashed[:SaltSize], salt)
	subtle.ConstantTimeCopy(1, hashed[SaltSize:], key)

	return hashed
}
Пример #9
0
func DeriveKey(password, salt []byte, N, r, p, n int) (key *Key, err error) {
	// Derive key using password and salt.
	k, err := scrypt.Key(password, salt, N, r, p, n)

	if err != nil {
		return
	}

	subtle.ConstantTimeCopy(1, key[:], k)
	return
}
Пример #10
0
// ChangePassword
func (this *Identity) ChangePassword(old, new string) (ok bool, err error) {
	// Recover master key.
	master, err := this.recoverMasterKey(old)

	if err != nil {
		return
	}

	salt := cryptoRand(saltLen)
	key, err := DeriveKey([]byte(new), salt, this.N, this.R, this.P, keyLen)

	if err != nil {
		return
	}

	key.Xor(master)
	subtle.ConstantTimeCopy(1, this.Key[:keyLen], key[:keyLen])
	subtle.ConstantTimeCopy(1, this.Check[:16], key.Hash()[:16])
	subtle.ConstantTimeCopy(1, this.Salt[:8], salt[:8])
	return
}
Пример #11
0
func main() {
	log.Printf("%d", subtle.ConstantTimeByteEq(43, 65))
	log.Printf("%d", subtle.ConstantTimeCompare([]byte("batman"), []byte("robin ")))

	bytes := make([]byte, 6)
	subtle.ConstantTimeCopy(1, bytes, []byte("batman"))
	log.Printf("%s", bytes)

	log.Printf("%d", subtle.ConstantTimeEq(256, 255))
	log.Printf("%d", subtle.ConstantTimeSelect(1, 2, 3))
	log.Printf("%d", subtle.ConstantTimeSelect(0, 2, 3))
}
Пример #12
0
// DecryptPKCS1v15SessionKey decrypts a session key using RSA and the padding scheme from PKCS#1 v1.5.
// If rand != nil, it uses RSA blinding to avoid timing side-channel attacks.
// It returns an error if the ciphertext is the wrong length or if the
// ciphertext is greater than the public modulus. Otherwise, no error is
// returned. If the padding is valid, the resulting plaintext message is copied
// into key. Otherwise, key is unchanged. These alternatives occur in constant
// time. It is intended that the user of this function generate a random
// session key beforehand and continue the protocol with the resulting value.
// This will remove any possibility that an attacker can learn any information
// about the plaintext.
// See ``Chosen Ciphertext Attacks Against Protocols Based on the RSA
// Encryption Standard PKCS #1'', Daniel Bleichenbacher, Advances in Cryptology
// (Crypto '98),
func DecryptPKCS1v15SessionKey(rand io.Reader, priv *PrivateKey, ciphertext []byte, key []byte) (err error) {
	k := (priv.N.BitLen() + 7) / 8
	if k-(len(key)+3+8) < 0 {
		err = DecryptionError{}
		return
	}

	valid, msg, err := decryptPKCS1v15(rand, priv, ciphertext)
	if err != nil {
		return
	}

	valid &= subtle.ConstantTimeEq(int32(len(msg)), int32(len(key)))
	subtle.ConstantTimeCopy(valid, key, msg)
	return
}
Пример #13
0
// DecryptPKCS1v15SessionKey decrypts a session key using RSA and the padding scheme from PKCS#1 v1.5.
// If rand != nil, it uses RSA blinding to avoid timing side-channel attacks.
// It returns an error if the ciphertext is the wrong length or if the
// ciphertext is greater than the public modulus. Otherwise, no error is
// returned. If the padding is valid, the resulting plaintext message is copied
// into key. Otherwise, key is unchanged. These alternatives occur in constant
// time. It is intended that the user of this function generate a random
// session key beforehand and continue the protocol with the resulting value.
// This will remove any possibility that an attacker can learn any information
// about the plaintext.
// See ``Chosen Ciphertext Attacks Against Protocols Based on the RSA
// Encryption Standard PKCS #1'', Daniel Bleichenbacher, Advances in Cryptology
// (Crypto '98).
func DecryptPKCS1v15SessionKey(rand io.Reader, priv *PrivateKey, ciphertext []byte, key []byte) (err error) {
	if err := checkPub(&priv.PublicKey); err != nil {
		return err
	}
	k := (priv.N.BitLen() + 7) / 8
	if k-(len(key)+3+8) < 0 {
		return ErrDecryption
	}

	valid, em, index, err := decryptPKCS1v15(rand, priv, ciphertext)
	if err != nil {
		return
	}

	if len(em) != k {
		// This should be impossible because decryptPKCS1v15 always
		// returns the full slice.
		return ErrDecryption
	}

	valid &= subtle.ConstantTimeEq(int32(len(em)-index), int32(len(key)))
	subtle.ConstantTimeCopy(valid, key, em[len(em)-len(key):])
	return
}
Пример #14
0
// decrypt an elgamal encrypted message, i2p style
func elgamalDecrypt(priv *elgamal.PrivateKey, data []byte, zeroPadding bool) (decrypted []byte, err error) {
	a := new(big.Int)
	b := new(big.Int)
	idx := 0
	if zeroPadding {
		idx++
	}
	a.SetBytes(data[idx : idx+256])
	if zeroPadding {
		idx++
	}
	b.SetBytes(data[idx+256:])

	// decrypt
	m := new(big.Int).Mod(new(big.Int).Mul(b, new(big.Int).Exp(a, new(big.Int).Sub(new(big.Int).Sub(priv.P, priv.X), one), priv.P)), priv.P).Bytes()

	// check digest
	d := sha256.Sum256(m[33:255])
	good := 0
	if subtle.ConstantTimeCompare(d[:], m[1:33]) == 1 {
		// decryption successful
		good = 1
	} else {
		// decrypt failed
		err = ElgDecryptFail
	}
	// copy result
	decrypted = make([]byte, 222)
	subtle.ConstantTimeCopy(good, decrypted, m[33:255])

	if good == 0 {
		// if decrypt failed nil out decrypted slice
		decrypted = nil
	}
	return
}
Пример #15
0
func constantTimeCopy(v int, x, y []byte) {
	subtle.ConstantTimeCopy(v, x, y)
}
Пример #16
0
// Sign returns the cryptographic signature of the []byte msg.
func (k *Key) Sign(msg []byte) (sig *Signature) {
	var pk *[ed25519.PrivateKeySize]byte
	subtle.ConstantTimeCopy(1, pk[:32], k[:])
	s := Signature(*ed25519.Sign(pk, msg))
	return &s
}
Пример #17
0
// PublicKey returns the corresponding public key.
func (k *Key) PublicKey() *Key {
	var pk *[ed25519.PrivateKeySize]byte
	subtle.ConstantTimeCopy(1, pk[:32], k[:])
	key := Key(*ed25519.GeneratePublicKey(pk))
	return &key
}