fix crash
- add session token check and fallback to shared secret in responder call too - use explicit length for the types of new messages - fix typo resp[resLen-1] = tokenFlag
This commit is contained in:
parent
b855f671a5
commit
714b955d6e
|
@ -17,7 +17,7 @@ var (
|
||||||
sigLen int = 65 // elliptic S256
|
sigLen int = 65 // elliptic S256
|
||||||
keyLen int = 32 // ECDSA
|
keyLen int = 32 // ECDSA
|
||||||
msgLen int = sigLen + 3*keyLen + 1 // 162
|
msgLen int = sigLen + 3*keyLen + 1 // 162
|
||||||
resLen int = 65
|
resLen int = 65 //
|
||||||
)
|
)
|
||||||
|
|
||||||
// aesSecret, macSecret, egressMac, ingress
|
// aesSecret, macSecret, egressMac, ingress
|
||||||
|
@ -133,7 +133,7 @@ func (self *cryptoId) initAuth(remotePubKeyDER, sessionToken []byte) (auth []byt
|
||||||
}
|
}
|
||||||
|
|
||||||
// verifyAuth is called by peer if it accepted (but not initiated) the connection
|
// verifyAuth is called by peer if it accepted (but not initiated) the connection
|
||||||
func (self *cryptoId) verifyAuth(auth, sharedSecret []byte, remotePubKey *ecdsa.PublicKey) (authResp []byte, respNonce []byte, initNonce []byte, remoteRandomPubKey *ecdsa.PublicKey, err error) {
|
func (self *cryptoId) verifyAuth(auth, sessionToken []byte, remotePubKey *ecdsa.PublicKey) (authResp []byte, respNonce []byte, initNonce []byte, remoteRandomPubKey *ecdsa.PublicKey, err error) {
|
||||||
var msg []byte
|
var msg []byte
|
||||||
fmt.Printf("encrypted message received: %v %x\n used pubkey: %x\n", len(auth), auth, crypto.FromECDSAPub(self.pubKey))
|
fmt.Printf("encrypted message received: %v %x\n used pubkey: %x\n", len(auth), auth, crypto.FromECDSAPub(self.pubKey))
|
||||||
// they prove that msg is meant for me,
|
// they prove that msg is meant for me,
|
||||||
|
@ -141,50 +141,57 @@ func (self *cryptoId) verifyAuth(auth, sharedSecret []byte, remotePubKey *ecdsa.
|
||||||
if msg, err = crypto.Decrypt(self.prvKey, auth); err != nil {
|
if msg, err = crypto.Decrypt(self.prvKey, auth); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
fmt.Printf("\nplaintext message retrieved: %v %x\n", len(msg), msg)
|
||||||
|
|
||||||
// var remoteNonce []byte = msg[msgLen-skLen-1 : msgLen-1]
|
var tokenFlag byte
|
||||||
|
if sessionToken == nil {
|
||||||
|
// no session token found means we need to generate shared secret.
|
||||||
|
// ecies shared secret is used as initial session token for new peers
|
||||||
|
// generate shared key from prv and remote pubkey
|
||||||
|
if sessionToken, err = ecies.ImportECDSA(self.prvKey).GenerateShared(ecies.ImportECDSAPublic(remotePubKey), sskLen, sskLen); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Printf("secret generated: %v %x", len(sessionToken), sessionToken)
|
||||||
|
// tokenFlag = 0x00 // redundant
|
||||||
|
} else {
|
||||||
|
// for known peers, we use stored token from the previous session
|
||||||
|
tokenFlag = 0x01
|
||||||
|
}
|
||||||
|
|
||||||
|
// the initiator nonce is read off the end of the message
|
||||||
initNonce = msg[msgLen-keyLen-1 : msgLen-1]
|
initNonce = msg[msgLen-keyLen-1 : msgLen-1]
|
||||||
// I prove that i own prv key (to derive shared secret, and read nonce off encrypted msg) and that I own shared secret
|
// I prove that i own prv key (to derive shared secret, and read nonce off encrypted msg) and that I own shared secret
|
||||||
// they prove they own the private key belonging to ecdhe-random-pubk
|
// they prove they own the private key belonging to ecdhe-random-pubk
|
||||||
var signedMsg = Xor(sharedSecret, initNonce)
|
// we can now reconstruct the signed message and recover the peers pubkey
|
||||||
|
var signedMsg = Xor(sessionToken, initNonce)
|
||||||
var remoteRandomPubKeyDER []byte
|
var remoteRandomPubKeyDER []byte
|
||||||
if remoteRandomPubKeyDER, err = secp256k1.RecoverPubkey(signedMsg, msg[:sigLen]); err != nil {
|
if remoteRandomPubKeyDER, err = secp256k1.RecoverPubkey(signedMsg, msg[:sigLen]); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
// convert to ECDSA standard
|
||||||
remoteRandomPubKey = crypto.ToECDSAPub(remoteRandomPubKeyDER)
|
remoteRandomPubKey = crypto.ToECDSAPub(remoteRandomPubKeyDER)
|
||||||
if remoteRandomPubKey == nil {
|
if remoteRandomPubKey == nil {
|
||||||
err = fmt.Errorf("invalid remote public key")
|
err = fmt.Errorf("invalid remote public key")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var resp = make([]byte, 2*keyLen+1)
|
// now we find ourselves a long task too, fill it random
|
||||||
// generate sskLen long nonce
|
var resp = make([]byte, resLen)
|
||||||
respNonce = msg[msgLen-keyLen-1 : msgLen-1]
|
// generate keyLen long nonce
|
||||||
|
respNonce = msg[resLen-keyLen-1 : msgLen-1]
|
||||||
if _, err = rand.Read(respNonce); err != nil {
|
if _, err = rand.Read(respNonce); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// generate random keypair
|
// generate random keypair for session
|
||||||
var ecdsaRandomPrvKey *ecdsa.PrivateKey
|
var ecdsaRandomPrvKey *ecdsa.PrivateKey
|
||||||
if ecdsaRandomPrvKey, err = crypto.GenerateKey(); err != nil {
|
if ecdsaRandomPrvKey, err = crypto.GenerateKey(); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// var ecdsaRandomPubKey *ecdsa.PublicKey
|
// responder auth message
|
||||||
// ecdsaRandomPubKey= &ecdsaRandomPrvKey.PublicKey
|
|
||||||
|
|
||||||
// message
|
|
||||||
// E(remote-pubk, ecdhe-random-pubk || nonce || 0x0)
|
// E(remote-pubk, ecdhe-random-pubk || nonce || 0x0)
|
||||||
copy(resp[:keyLen], crypto.FromECDSAPub(&ecdsaRandomPrvKey.PublicKey))
|
copy(resp[:keyLen], crypto.FromECDSAPub(&ecdsaRandomPrvKey.PublicKey))
|
||||||
// pubkey copied to the correct segment.
|
|
||||||
copy(resp[keyLen:2*keyLen], self.pubKeyDER)
|
|
||||||
// nonce is already in the slice
|
// nonce is already in the slice
|
||||||
// stick tokenFlag byte to the end
|
resp[resLen-1] = tokenFlag
|
||||||
var tokenFlag byte
|
|
||||||
if sharedSecret == nil {
|
|
||||||
} else {
|
|
||||||
// for known peers, we use stored token from the previous session
|
|
||||||
tokenFlag = 0x01
|
|
||||||
}
|
|
||||||
resp[resLen] = tokenFlag
|
|
||||||
|
|
||||||
// encrypt using remote-pubk
|
// encrypt using remote-pubk
|
||||||
// auth = eciesEncrypt(remote-pubk, msg)
|
// auth = eciesEncrypt(remote-pubk, msg)
|
||||||
|
|
Loading…
Reference in New Issue