/** * Initiate a new session by sending an initial KeyExchangeMessage to the recipient. * * @return the KeyExchangeMessage to deliver. */ public KeyExchangeMessage Process() { lock (SessionCipher.SESSION_LOCK) { try { uint sequence = KeyHelper.GetRandomSequence(65534) + 1; uint flags = KeyExchangeMessage.INITIATE_FLAG; ECKeyPair baseKey = Curve.GenerateKeyPair(); ECKeyPair ratchetKey = Curve.GenerateKeyPair(); IdentityKeyPair identityKey = identityKeyStore.GetIdentityKeyPair(); byte[] baseKeySignature = Curve.CalculateSignature(identityKey.GetPrivateKey(), baseKey.GetPublicKey().Serialize()); SessionRecord sessionRecord = sessionStore.LoadSession(remoteAddress); sessionRecord.GetSessionState().SetPendingKeyExchange(sequence, baseKey, ratchetKey, identityKey); sessionStore.StoreSession(remoteAddress, sessionRecord); return(new KeyExchangeMessage(2, sequence, flags, baseKey.GetPublicKey(), baseKeySignature, ratchetKey.GetPublicKey(), identityKey.GetPublicKey())); } catch (InvalidKeyException e) { throw new Exception(e.Message); } } }
/** * Generate an identity key pair. Clients should only do this once, * at install time. * * @return the generated IdentityKeyPair. */ public static IdentityKeyPair GenerateIdentityKeyPair() { ECKeyPair keyPair = Curve.GenerateKeyPair(); IdentityKey publicKey = new IdentityKey(keyPair.GetPublicKey()); return(new IdentityKeyPair(publicKey, keyPair.GetPrivateKey())); }
/** * Build a new session from a {@link org.whispersystems.libaxolotl.state.PreKeyBundle} retrieved from * a server. * * @param preKey A PreKey for the destination recipient, retrieved from a server. * @throws InvalidKeyException when the {@link org.whispersystems.libaxolotl.state.PreKeyBundle} is * badly formatted. * @throws org.whispersystems.libaxolotl.UntrustedIdentityException when the sender's * {@link IdentityKey} is not * trusted. */ public void Process(PreKeyBundle preKey) { lock (SessionCipher.SESSION_LOCK) { if (!identityKeyStore.IsTrustedIdentity(remoteAddress.GetName(), preKey.GetIdentityKey())) { throw new UntrustedIdentityException(remoteAddress.GetName(), preKey.GetIdentityKey()); } if (preKey.GetSignedPreKey() != null && !Curve.VerifySignature(preKey.GetIdentityKey().GetPublicKey(), preKey.GetSignedPreKey().Serialize(), preKey.GetSignedPreKeySignature())) { throw new InvalidKeyException("Invalid Signature on Device Key!"); } if (preKey.GetSignedPreKey() == null && preKey.GetPreKey() == null) { throw new InvalidKeyException("Both Signed and Unsigned Prekeys are Absent!"); } bool supportsV3 = preKey.GetSignedPreKey() != null; SessionRecord sessionRecord = sessionStore.LoadSession(remoteAddress); ECKeyPair ourBaseKey = Curve.GenerateKeyPair(); ECPublicKey theirSignedPreKey = supportsV3 ? preKey.GetSignedPreKey() : preKey.GetPreKey(); ECPublicKey test = preKey.GetPreKey(); // TODO: Cleanup May <ECPublicKey> theirOneTimePreKey = (test == null) ? May <ECPublicKey> .NoValue : new May <ECPublicKey>(test); May <uint> theirOneTimePreKeyId = theirOneTimePreKey.HasValue ? new May <uint>(preKey.GetPreKeyId()) : May <uint> .NoValue; AliceAxolotlParameters.Builder parameters = AliceAxolotlParameters.NewBuilder(); parameters.SetOurBaseKey(ourBaseKey) .SetOurIdentityKey(identityKeyStore.GetIdentityKeyPair()) .SetTheirIdentityKey(preKey.GetIdentityKey()) .SetTheirSignedPreKey(theirSignedPreKey) .SetTheirRatchetKey(theirSignedPreKey) .SetTheirOneTimePreKey(supportsV3 ? theirOneTimePreKey : May <ECPublicKey> .NoValue); if (!sessionRecord.IsFresh()) { sessionRecord.ArchiveCurrentState(); } RatchetingSession.InitializeSession(sessionRecord.GetSessionState(), supportsV3 ? (uint)3 : 2, parameters.Create()); sessionRecord.GetSessionState().SetUnacknowledgedPreKeyMessage(theirOneTimePreKeyId, preKey.GetSignedPreKeyId(), ourBaseKey.GetPublicKey()); sessionRecord.GetSessionState().SetLocalRegistrationId(identityKeyStore.GetLocalRegistrationId()); sessionRecord.GetSessionState().SetRemoteRegistrationId(preKey.GetRegistrationId()); sessionRecord.GetSessionState().SetAliceBaseKey(ourBaseKey.GetPublicKey().Serialize()); sessionStore.StoreSession(remoteAddress, sessionRecord); identityKeyStore.SaveIdentity(remoteAddress.GetName(), preKey.GetIdentityKey()); } }
public SignedPreKeyRecord(uint id, ulong timestamp, ECKeyPair keyPair, byte[] signature) { this.structure = SignedPreKeyRecordStructure.CreateBuilder() .SetId(id) .SetPublicKey(ByteString.CopyFrom(keyPair.GetPublicKey().Serialize())) .SetPrivateKey(ByteString.CopyFrom(keyPair.GetPrivateKey().Serialize())) .SetSignature(ByteString.CopyFrom(signature)) .SetTimestamp(timestamp) .Build(); }
public PreKeyRecord(uint id, ECKeyPair keyPair) { this.structure = PreKeyRecordStructure.CreateBuilder() .SetId(id) .SetPublicKey(ByteString.CopyFrom(keyPair.GetPublicKey() .Serialize())) .SetPrivateKey(ByteString.CopyFrom(keyPair.GetPrivateKey() .Serialize())) .Build(); }
public void SetSenderChain(ECKeyPair senderRatchetKeyPair, ChainKey chainKey) { Chain.Types.ChainKey chainKeyStructure = Chain.Types.ChainKey.CreateBuilder() .SetKey(ByteString.CopyFrom(chainKey.GetKey())) .SetIndex(chainKey.GetIndex()) .Build(); Chain senderChain = Chain.CreateBuilder() .SetSenderRatchetKey(ByteString.CopyFrom(senderRatchetKeyPair.GetPublicKey().Serialize())) .SetSenderRatchetKeyPrivate(ByteString.CopyFrom(senderRatchetKeyPair.GetPrivateKey().Serialize())) .SetChainKey(chainKeyStructure) .Build(); this.sessionStructure = this.sessionStructure.ToBuilder().SetSenderChain(senderChain).Build(); }
public void SetPendingKeyExchange(uint sequence, ECKeyPair ourBaseKey, ECKeyPair ourRatchetKey, IdentityKeyPair ourIdentityKey) { PendingKeyExchange structure = PendingKeyExchange.CreateBuilder() .SetSequence(sequence) .SetLocalBaseKey(ByteString.CopyFrom(ourBaseKey.GetPublicKey().Serialize())) .SetLocalBaseKeyPrivate(ByteString.CopyFrom(ourBaseKey.GetPrivateKey().Serialize())) .SetLocalRatchetKey(ByteString.CopyFrom(ourRatchetKey.GetPublicKey().Serialize())) .SetLocalRatchetKeyPrivate(ByteString.CopyFrom(ourRatchetKey.GetPrivateKey().Serialize())) .SetLocalIdentityKey(ByteString.CopyFrom(ourIdentityKey.GetPublicKey().Serialize())) .SetLocalIdentityKeyPrivate(ByteString.CopyFrom(ourIdentityKey.GetPrivateKey().Serialize())) .Build(); this.sessionStructure = this.sessionStructure.ToBuilder() .SetPendingKeyExchange(structure) .Build(); }
public static SignatureData SignMessage(byte[] message, ECKeyPair keys, bool needToHash) { BigInteger publicKey = keys.GetPublicKey(); var messageHash = needToHash ? Hash.HashBlake2B(message) : message; var recId = -1; ECDSASignature sig = keys.Sign(messageHash); for (int i = 0; i < 4; i++) { BigInteger k = RecoverFromSignature(i, sig, messageHash); if (k != null && k.Equals(publicKey)) { recId = i; break; } } if (recId == -1) { throw new FormatException("Sign the data failed."); } if (recId == 2 || recId == 3) { throw new InvalidOperationException("Recovery is not valid for VeChain MainNet."); } byte v = (byte)recId; sig.R.ToByteArray(); byte[] r = BigIntToBytesWithPadding(sig.R, 32); byte[] s = BigIntToBytesWithPadding(sig.S, 32); return(new SignatureData(v, r, s)); }
public SenderKeyState(uint id, uint iteration, byte[] chainKey, ECKeyPair signatureKey) : this(id, iteration, chainKey, signatureKey.GetPublicKey(), new May <ECPrivateKey>(signatureKey.GetPrivateKey())) { }
/** * Generate a signed PreKey * * @param identityKeyPair The local client's identity key pair. * @param signedPreKeyId The PreKey id to assign the generated signed PreKey * * @return the generated signed PreKey * @throws InvalidKeyException when the provided identity key is invalid */ public static SignedPreKeyRecord GenerateSignedPreKey(IdentityKeyPair identityKeyPair, uint signedPreKeyId) { ECKeyPair keyPair = Curve.GenerateKeyPair(); byte[] signature = Curve.CalculateSignature(identityKeyPair.GetPrivateKey(), keyPair.GetPublicKey().Serialize()); return(new SignedPreKeyRecord(signedPreKeyId, GetTime(), keyPair, signature)); }