func getSessionKey(ss session.Store, hash string) (*uid.KeyEntry, error) { jsn, privKey, err := ss.GetSessionKey(hash) if err != nil { return nil, err } ke, err := uid.NewJSONKeyEntry([]byte(jsn)) if err != nil { return nil, err } if privKey != "" { if err := ke.SetPrivateKey(privKey); err != nil { return nil, err } } return ke, err }
func setNextSenderSessionPub( keyStore session.Store, sessionState *session.State, sessionStateKey string, rand io.Reader, ) (*uid.KeyEntry, error) { // create next session key var nextSenderSession uid.KeyEntry if err := nextSenderSession.InitDHKey(rand); err != nil { return nil, err } // store next session key if err := addSessionKey(keyStore, &nextSenderSession); err != nil { return nil, err } // update session state sessionState.NextSenderSessionPub = &nextSenderSession err := keyStore.SetSessionState(sessionStateKey, sessionState) if err != nil { return nil, err } return &nextSenderSession, nil }
// generateMessageKeys generates the next numOfKeys many session keys from // from rootKey for given senderIdentity and recipientIdentity. // If recipientKeys is true the generated sender and reciever keys are stored in // reverse order. // It uses senderSessionPub and recipientPub in the process and calls // keyStore.StoresSession and keyStore.SetSessionState to store the result. func generateMessageKeys( senderIdentity, recipientIdentity string, senderIdentityPubkeyHash, recipientIdentityPubkeyHash string, rootKey *[32]byte, recipientKeys bool, senderSessionPub, recipientPub *[32]byte, numOfKeys uint64, keyStore session.Store, ) error { var ( identities string send []string recv []string ) // identity_fix = HASH(SORT(SenderNym, RecipientNym)) if senderIdentity < recipientIdentity { identities = senderIdentity + recipientIdentity } else { identities = recipientIdentity + senderIdentity } identityFix := cipher.SHA512([]byte(identities)) recipientPubHash := cipher.SHA512(recipientPub[:]) senderSessionPubHash := cipher.SHA512(senderSessionPub[:]) chainKey := rootKey[:] for i := uint64(0); i < numOfKeys; i++ { // messagekey_send[i] = HMAC_HASH(chainkey, "MESSAGE" | HASH(RecipientPub) | identity_fix) buffer := append([]byte("MESSAGE"), recipientPubHash...) buffer = append(buffer, identityFix...) send = append(send, base64.Encode(cipher.HMAC(chainKey, buffer))) // messagekey_recv[i] = HMAC_HASH(chainkey, "MESSAGE" | HASH(SenderSessionPub) | identity_fix) buffer = append([]byte("MESSAGE"), senderSessionPubHash...) buffer = append(buffer, identityFix...) recv = append(recv, base64.Encode(cipher.HMAC(chainKey, buffer))) // chainkey = HMAC_HASH(chainkey, "CHAIN" ) chainKey = cipher.HMAC(chainKey, []byte("CHAIN"))[:32] } // calculate root key hash rootKeyHash := base64.Encode(cipher.SHA512(rootKey[:])) bzero.Bytes(rootKey[:]) // reverse key material, if necessary if recipientKeys { send, recv = recv, send } // store session var sessionKey string if recipientKeys { key := recipientIdentityPubkeyHash key += senderIdentityPubkeyHash key += base64.Encode(cipher.SHA512(recipientPub[:])) key += base64.Encode(cipher.SHA512(senderSessionPub[:])) sessionKey = base64.Encode(cipher.SHA512([]byte(key))) } else { key := senderIdentityPubkeyHash key += recipientIdentityPubkeyHash key += base64.Encode(cipher.SHA512(senderSessionPub[:])) key += base64.Encode(cipher.SHA512(recipientPub[:])) sessionKey = base64.Encode(cipher.SHA512([]byte(key))) } err := keyStore.StoreSession(sessionKey, rootKeyHash, base64.Encode(chainKey), send, recv) if err != nil { return err } return nil }
func addSessionKey(ss session.Store, ke *uid.KeyEntry) error { ct := uint64(times.Now()) + CleanupTime return ss.AddSessionKey(ke.HASH, string(ke.JSON()), ke.PrivateKey(), ct) }