private SenderKeyState(uint id, uint iteration, byte[] chainKey, ECPublicKey signatureKeyPublic, May<ECPrivateKey> signatureKeyPrivate) { SenderKeyStateStructure.Types.SenderChainKey senderChainKeyStructure = SenderKeyStateStructure.Types.SenderChainKey.CreateBuilder() .SetIteration(iteration) .SetSeed(ByteString.CopyFrom(chainKey)) .Build(); SenderKeyStateStructure.Types.SenderSigningKey.Builder signingKeyStructure = SenderKeyStateStructure.Types.SenderSigningKey.CreateBuilder() .SetPublic(ByteString.CopyFrom(signatureKeyPublic.serialize())); if (signatureKeyPrivate.HasValue) { signingKeyStructure.SetPrivate(ByteString.CopyFrom(signatureKeyPrivate.ForceGetValue().serialize())); } this.senderKeyStateStructure = SenderKeyStateStructure.CreateBuilder() .SetSenderKeyId(id) .SetSenderChainKey(senderChainKeyStructure) .SetSenderSigningKey(signingKeyStructure) .Build(); }
public KeyExchangeMessage(uint messageVersion, uint sequence, uint flags, ECPublicKey baseKey, byte[] baseKeySignature, ECPublicKey ratchetKey, IdentityKey identityKey) { this.supportedVersion = CiphertextMessage.CURRENT_VERSION; this.version = messageVersion; this.sequence = sequence; this.flags = flags; this.baseKey = baseKey; this.baseKeySignature = baseKeySignature; this.ratchetKey = ratchetKey; this.identityKey = identityKey; byte[] version = { ByteUtil.intsToByteHighAndLow((int)this.version, (int)this.supportedVersion) }; WhisperProtos.KeyExchangeMessage.Builder builder = WhisperProtos.KeyExchangeMessage .CreateBuilder() .SetId((sequence << 5) | flags) //(sequence << 5) | flags .SetBaseKey(ByteString.CopyFrom(baseKey.serialize())) .SetRatchetKey(ByteString.CopyFrom(ratchetKey.serialize())) .SetIdentityKey(ByteString.CopyFrom(identityKey.serialize())); if (messageVersion >= 3) { builder.SetBaseKeySignature(ByteString.CopyFrom(baseKeySignature)); } this.serialized = ByteUtil.combine(version, builder.Build().ToByteArray()); }
public PreKeyWhisperMessage(uint messageVersion, uint registrationId, May<uint> preKeyId, uint signedPreKeyId, ECPublicKey baseKey, IdentityKey identityKey, WhisperMessage message) { this.version = messageVersion; this.registrationId = registrationId; this.preKeyId = preKeyId; this.signedPreKeyId = signedPreKeyId; this.baseKey = baseKey; this.identityKey = identityKey; this.message = message; WhisperProtos.PreKeyWhisperMessage.Builder builder = WhisperProtos.PreKeyWhisperMessage.CreateBuilder() .SetSignedPreKeyId(signedPreKeyId) .SetBaseKey(ByteString.CopyFrom(baseKey.serialize())) .SetIdentityKey(ByteString.CopyFrom(identityKey.serialize())) .SetMessage(ByteString.CopyFrom(message.serialize())) .SetRegistrationId(registrationId); if (preKeyId.HasValue) // .isPresent() { builder.SetPreKeyId(preKeyId.ForceGetValue()); // get() } byte[] versionBytes = { ByteUtil.intsToByteHighAndLow((int)this.version, (int)CURRENT_VERSION) }; byte[] messageBytes = builder.Build().ToByteArray(); this.serialized = ByteUtil.combine(versionBytes, messageBytes); }
public void addSenderKeyState(uint id, uint iteration, byte[] chainKey, ECPublicKey signatureKey) { senderKeyStates.AddFirst(new SenderKeyState(id, iteration, chainKey, signatureKey)); if (senderKeyStates.Count > MAX_STATES) { senderKeyStates.RemoveLast(); } }
public Pair<RootKey, ChainKey> createChain(ECPublicKey theirRatchetKey, ECKeyPair ourRatchetKey) { byte[] sharedSecret = Curve.calculateAgreement(theirRatchetKey, ourRatchetKey.getPrivateKey()); byte[] derivedSecretBytes = kdf.deriveSecrets(sharedSecret, key, Encoding.UTF8.GetBytes("WhisperRatchet"), DerivedRootSecrets.SIZE); DerivedRootSecrets derivedSecrets = new DerivedRootSecrets(derivedSecretBytes); RootKey newRootKey = new RootKey(kdf, derivedSecrets.getRootKey()); ChainKey newChainKey = new ChainKey(kdf, derivedSecrets.getChainKey(), 0); return new Pair<RootKey, ChainKey>(newRootKey, newChainKey); }
public static bool verifySignature(ECPublicKey signingKey, byte[] message, byte[] signature) { if (signingKey.getType() == DJB_TYPE) { return Curve25519.getInstance(Curve25519ProviderType.BEST) .verifySignature(((DjbECPublicKey)signingKey).getPublicKey(), message, signature); } else { throw new InvalidKeyException("Unknown type: " + signingKey.getType()); } }
public PreKeyBundle(uint registrationId, uint deviceId, uint preKeyId, ECPublicKey preKeyPublic, uint signedPreKeyId, ECPublicKey signedPreKeyPublic, byte[] signedPreKeySignature, IdentityKey identityKey) { this.registrationId = registrationId; this.deviceId = deviceId; this.preKeyId = preKeyId; this.preKeyPublic = preKeyPublic; this.signedPreKeyId = signedPreKeyId; this.signedPreKeyPublic = signedPreKeyPublic; this.signedPreKeySignature = signedPreKeySignature; this.identityKey = identityKey; }
public SenderKeyDistributionMessage(uint id, uint iteration, byte[] chainKey, ECPublicKey signatureKey) { byte[] version = { ByteUtil.intsToByteHighAndLow((int)CURRENT_VERSION, (int)CURRENT_VERSION) }; byte[] protobuf = WhisperProtos.SenderKeyDistributionMessage.CreateBuilder() .SetId(id) .SetIteration(iteration) .SetChainKey(ByteString.CopyFrom(chainKey)) .SetSigningKey(ByteString.CopyFrom(signatureKey.serialize())) .Build().ToByteArray(); this.id = id; this.iteration = iteration; this.chainKey = chainKey; this.signatureKey = signatureKey; this.serialized = ByteUtil.combine(version, protobuf); }
BobAxolotlParameters(IdentityKeyPair ourIdentityKey, ECKeyPair ourSignedPreKey, ECKeyPair ourRatchetKey, May<ECKeyPair> ourOneTimePreKey, IdentityKey theirIdentityKey, ECPublicKey theirBaseKey) { this.ourIdentityKey = ourIdentityKey; this.ourSignedPreKey = ourSignedPreKey; this.ourRatchetKey = ourRatchetKey; this.ourOneTimePreKey = ourOneTimePreKey; this.theirIdentityKey = theirIdentityKey; this.theirBaseKey = theirBaseKey; if (ourIdentityKey == null || ourSignedPreKey == null || ourRatchetKey == null || ourOneTimePreKey == null || theirIdentityKey == null || theirBaseKey == null) { throw new Exception("Null value!"); } }
SymmetricAxolotlParameters(ECKeyPair ourBaseKey, ECKeyPair ourRatchetKey, IdentityKeyPair ourIdentityKey, ECPublicKey theirBaseKey, ECPublicKey theirRatchetKey, IdentityKey theirIdentityKey) { this.ourBaseKey = ourBaseKey; this.ourRatchetKey = ourRatchetKey; this.ourIdentityKey = ourIdentityKey; this.theirBaseKey = theirBaseKey; this.theirRatchetKey = theirRatchetKey; this.theirIdentityKey = theirIdentityKey; if (ourBaseKey == null || ourRatchetKey == null || ourIdentityKey == null || theirBaseKey == null || theirRatchetKey == null || theirIdentityKey == null) { throw new Exception("Null values!"); } }
public WhisperMessage(byte[] serialized) { try { byte[][] messageParts = ByteUtil.split(serialized, 1, serialized.Length - 1 - MAC_LENGTH, MAC_LENGTH); byte version = messageParts[0][0]; byte[] message = messageParts[1]; byte[] mac = messageParts[2]; if (ByteUtil.highBitsToInt(version) <= CiphertextMessage.UNSUPPORTED_VERSION) { throw new LegacyMessageException("Legacy message: " + ByteUtil.highBitsToInt(version)); } if (ByteUtil.highBitsToInt(version) > CURRENT_VERSION) { throw new InvalidMessageException("Unknown version: " + ByteUtil.highBitsToInt(version)); } WhisperProtos.WhisperMessage whisperMessage = WhisperProtos.WhisperMessage.ParseFrom(message); if (!whisperMessage.HasCiphertext || !whisperMessage.HasCounter || !whisperMessage.HasRatchetKey) { throw new InvalidMessageException("Incomplete message."); } this.serialized = serialized; this.senderRatchetKey = Curve.decodePoint(whisperMessage.RatchetKey.ToByteArray(), 0); this.messageVersion = (uint)ByteUtil.highBitsToInt(version); this.counter = whisperMessage.Counter; this.previousCounter = whisperMessage.PreviousCounter; this.ciphertext = whisperMessage.Ciphertext.ToByteArray(); } catch (/*InvalidProtocolBufferException | InvalidKeyException | Parse*/Exception e) { throw new InvalidMessageException(e); } }
public SenderKeyDistributionMessage(byte[] serialized) { try { byte[][] messageParts = ByteUtil.split(serialized, 1, serialized.Length - 1); byte version = messageParts[0][0]; byte[] message = messageParts[1]; if (ByteUtil.highBitsToInt(version) < CiphertextMessage.CURRENT_VERSION) { throw new LegacyMessageException("Legacy message: " + ByteUtil.highBitsToInt(version)); } if (ByteUtil.highBitsToInt(version) > CURRENT_VERSION) { throw new InvalidMessageException("Unknown version: " + ByteUtil.highBitsToInt(version)); } WhisperProtos.SenderKeyDistributionMessage distributionMessage = WhisperProtos.SenderKeyDistributionMessage.ParseFrom(message); if (!distributionMessage.HasId || !distributionMessage.HasIteration || !distributionMessage.HasChainKey || !distributionMessage.HasSigningKey) { throw new InvalidMessageException("Incomplete message."); } this.serialized = serialized; this.id = distributionMessage.Id; this.iteration = distributionMessage.Iteration; this.chainKey = distributionMessage.ChainKey.ToByteArray(); this.signatureKey = Curve.decodePoint(distributionMessage.SigningKey.ToByteArray(), 0); } catch (Exception e) { //InvalidProtocolBufferException | InvalidKey throw new InvalidMessageException(e); } }
public PreKeyWhisperMessage(byte[] serialized) { try { this.version = (uint)ByteUtil.highBitsToInt(serialized[0]); if (this.version > CiphertextMessage.CURRENT_VERSION) { throw new InvalidVersionException("Unknown version: " + this.version); } WhisperProtos.PreKeyWhisperMessage preKeyWhisperMessage = WhisperProtos.PreKeyWhisperMessage.ParseFrom(ByteString.CopyFrom(serialized, 1, serialized.Length - 1)); if ((version == 2 && !preKeyWhisperMessage.HasPreKeyId) || (version == 3 && !preKeyWhisperMessage.HasSignedPreKeyId) || !preKeyWhisperMessage.HasBaseKey || !preKeyWhisperMessage.HasIdentityKey || !preKeyWhisperMessage.HasMessage) { throw new InvalidMessageException("Incomplete message."); } this.serialized = serialized; this.registrationId = preKeyWhisperMessage.RegistrationId; this.preKeyId = preKeyWhisperMessage.HasPreKeyId ? new May<uint>(preKeyWhisperMessage.PreKeyId) : May<uint>.NoValue; this.signedPreKeyId = preKeyWhisperMessage.HasSignedPreKeyId ? preKeyWhisperMessage.SignedPreKeyId : uint.MaxValue; // -1 this.baseKey = Curve.decodePoint(preKeyWhisperMessage.BaseKey.ToByteArray(), 0); this.identityKey = new IdentityKey(Curve.decodePoint(preKeyWhisperMessage.IdentityKey.ToByteArray(), 0)); this.message = new WhisperMessage(preKeyWhisperMessage.Message.ToByteArray()); } catch (Exception e) { //(InvalidProtocolBufferException | InvalidKeyException | LegacyMessage throw new InvalidMessageException(e.Message); } }
public WhisperMessage(uint messageVersion, byte[] macKey, ECPublicKey senderRatchetKey, uint counter, uint previousCounter, byte[] ciphertext, IdentityKey senderIdentityKey, IdentityKey receiverIdentityKey) { byte[] version = { ByteUtil.intsToByteHighAndLow((int)messageVersion, (int)CURRENT_VERSION) }; byte[] message = WhisperProtos.WhisperMessage.CreateBuilder() .SetRatchetKey(ByteString.CopyFrom(senderRatchetKey.serialize())) .SetCounter(counter) .SetPreviousCounter(previousCounter) .SetCiphertext(ByteString.CopyFrom(ciphertext)) .Build().ToByteArray(); byte[] mac = getMac(messageVersion, senderIdentityKey, receiverIdentityKey, macKey, ByteUtil.combine(version, message)); this.serialized = ByteUtil.combine(version, message, mac); this.senderRatchetKey = senderRatchetKey; this.counter = counter; this.previousCounter = previousCounter; this.ciphertext = ciphertext; this.messageVersion = messageVersion; }
public void setReceiverChainKey(ECPublicKey senderEphemeral, ChainKey chainKey) { Pair<Chain, uint> chainAndIndex = getReceiverChain(senderEphemeral); Chain chain = chainAndIndex.first(); Chain.Types.ChainKey chainKeyStructure = Chain.Types.ChainKey.CreateBuilder() .SetKey(ByteString.CopyFrom(chainKey.getKey())) .SetIndex(chainKey.getIndex()) .Build(); Chain updatedChain = chain.ToBuilder().SetChainKey(chainKeyStructure).Build(); this.sessionStructure = this.sessionStructure.ToBuilder() .SetReceiverChains((int)chainAndIndex.second(), updatedChain) // TODO: conv .Build(); }
public UnacknowledgedPreKeyMessageItems(May<uint> preKeyId, uint signedPreKeyId, ECPublicKey baseKey) { this.preKeyId = preKeyId; this.signedPreKeyId = signedPreKeyId; this.baseKey = baseKey; }
public void addReceiverChain(ECPublicKey senderRatchetKey, ChainKey chainKey) { Chain.Types.ChainKey chainKeyStructure = Chain.Types.ChainKey.CreateBuilder() .SetKey(ByteString.CopyFrom(chainKey.getKey())) .SetIndex(chainKey.getIndex()) .Build(); Chain chain = Chain.CreateBuilder() .SetChainKey(chainKeyStructure) .SetSenderRatchetKey(ByteString.CopyFrom(senderRatchetKey.serialize())) .Build(); this.sessionStructure = this.sessionStructure.ToBuilder().AddReceiverChains(chain).Build(); if (this.sessionStructure.ReceiverChainsList.Count > 5) { this.sessionStructure = this.sessionStructure.ToBuilder()/*.ClearReceiverChains()*/.Build(); //RemoveReceiverChains(0) TODO: why does it work without } }
public MessageKeys removeMessageKeys(ECPublicKey senderEphemeral, uint counter) { Pair<Chain, uint> chainAndIndex = getReceiverChain(senderEphemeral); Chain chain = chainAndIndex.first(); if (chain == null) { return null; } List<Chain.Types.MessageKey> messageKeyList = new List<Chain.Types.MessageKey>(chain.MessageKeysList); IEnumerator<Chain.Types.MessageKey> messageKeyIterator = messageKeyList.GetEnumerator(); MessageKeys result = null; while (messageKeyIterator.MoveNext()) //hasNext() { Chain.Types.MessageKey messageKey = messageKeyIterator.Current; // next() if (messageKey.Index == counter) { result = new MessageKeys(messageKey.CipherKey.ToByteArray(), messageKey.MacKey.ToByteArray(), messageKey.Iv.ToByteArray(), messageKey.Index); messageKeyList.Remove(messageKey); //messageKeyIterator.remove(); break; } } Chain updatedChain = chain.ToBuilder().ClearMessageKeys() .AddRangeMessageKeys(messageKeyList) // AddAllMessageKeys .Build(); this.sessionStructure = this.sessionStructure.ToBuilder() .SetReceiverChains((int)chainAndIndex.second(), updatedChain) // TODO: conv .Build(); return result; }
public Builder SetTheirRatchetKey(ECPublicKey theirRatchetKey) { this.theirRatchetKey = theirRatchetKey; return(this); }
private Pair<Chain, uint> getReceiverChain(ECPublicKey senderEphemeral) { IList<Chain> receiverChains = sessionStructure.ReceiverChainsList; uint index = 0; foreach (Chain receiverChain in receiverChains) { try { ECPublicKey chainSenderRatchetKey = Curve.decodePoint(receiverChain.SenderRatchetKey.ToByteArray(), 0); if (chainSenderRatchetKey.Equals(senderEphemeral)) { return new Pair<Chain, uint>(receiverChain, index); } } catch (InvalidKeyException e) { Debug.WriteLine(e.ToString(), "SessionRecordV2"); } index++; } return null; }
public IdentityKey(byte[] bytes, int offset) { publicKey = Curve.decodePoint(bytes, offset); }
public static CertificateValidator GetCertificateValidator() { ECPublicKey unidentifiedSenderTrustRoot = Curve.decodePoint(Base64.Decode(UNIDENTIFIED_SENDER_TRUST_ROOT), 0); return(new CertificateValidator(unidentifiedSenderTrustRoot)); }
public Builder setTheirBaseKey(ECPublicKey theirBaseKey) { this.theirBaseKey = theirBaseKey; return(this); }
public IdentityKey(ECPublicKey publicKey) { this.publicKey = publicKey; }
public bool VerifySecuritySignature(ECPublicKey publicKey, byte[] signature) { return(VerifySignature(publicKey, securityString, signature)); }
public bool VerifySignature(ECPublicKey publicKey, string data, byte[] signature) { return(VerifySignature(publicKey, StringToBytes(data), signature)); }
public ECKeyPair(ECPublicKey publicKey, ECPrivateKey privateKey) { this.publicKey = publicKey; this.privateKey = privateKey; }
public async Task <List <PreKeyBundle> > getPreKeys(SignalServiceAddress destination, uint deviceIdInteger)// throws IOException { try { string deviceId = deviceIdInteger.ToString(); if (deviceId.Equals("1")) { deviceId = "*"; } string path = string.Format(PREKEY_DEVICE_PATH, destination.getNumber(), deviceId); if (destination.getRelay().HasValue) { path = path + "?relay=" + destination.getRelay().ForceGetValue(); } string responseText = await makeRequest(path, "GET", null); PreKeyResponse response = JsonUtil.fromJson <PreKeyResponse>(responseText); List <PreKeyBundle> bundles = new List <PreKeyBundle>(); foreach (PreKeyResponseItem device in response.getDevices()) { ECPublicKey preKey = null; ECPublicKey signedPreKey = null; byte[] signedPreKeySignature = null; int preKeyId = -1; int signedPreKeyId = -1; if (device.getSignedPreKey() != null) { signedPreKey = device.getSignedPreKey().getPublicKey(); signedPreKeyId = (int)device.getSignedPreKey().getKeyId(); // TODO: whacky signedPreKeySignature = device.getSignedPreKey().getSignature(); } if (device.getPreKey() != null) { preKeyId = (int)device.getPreKey().getKeyId();// TODO: whacky preKey = device.getPreKey().getPublicKey(); } bundles.Add(new PreKeyBundle(device.getRegistrationId(), device.getDeviceId(), (uint)preKeyId, preKey, (uint)signedPreKeyId, signedPreKey, signedPreKeySignature, response.getIdentityKey())); // TODO: whacky } return(bundles); } /*catch (JsonUtil.JsonParseException e) * { * throw new IOException(e); * }*/ catch (NotFoundException nfe) { throw new UnregisteredUserException(destination.getNumber(), nfe); } }
private static bool IsAlice(ECPublicKey ourKey, ECPublicKey theirKey) { return(ourKey.CompareTo(theirKey) < 0); }
static ECPrivateKey DecodePrivateKeyEC(AsnElt ak, ECCurve curve) { ak.CheckNumSubMin(2); ak.GetSub(0).CheckTag(AsnElt.INTEGER); ak.GetSub(1).CheckTag(AsnElt.OCTET_STRING); long kt = ak.GetSub(0).GetInteger(); if (kt != 1) { throw new AsnException( "Unsupported EC key type: " + kt); } byte[] x = ak.GetSub(1).CopyValue(); byte[] pub = null; int n = ak.Sub.Length; int p = 2; if (p < n) { AsnElt acc = ak.GetSub(p); if (acc.TagClass == AsnElt.CONTEXT && acc.TagValue == 0) { acc.CheckNumSub(1); acc = acc.GetSub(0); ECCurve curve2 = DecodeCurve(acc); /* * Here, we support only named curves. */ /* obsolete */ if (curve == null) { curve = curve2; } else if (!curve.Equals(curve2)) { throw new AsnException(string.Format( "Inconsistent curve" + " specification ({0} / {1})", curve.Name, curve2.Name)); } p++; } } if (p < n) { AsnElt acc = ak.GetSub(p); if (acc.TagClass == AsnElt.CONTEXT && acc.TagValue == 1) { acc.CheckNumSub(1); acc = acc.GetSub(0); acc.CheckTag(AsnElt.BIT_STRING); pub = acc.GetBitString(); } } if (curve == null) { throw new AsnException("No curve specified for EC key"); } ECPrivateKey esk = new ECPrivateKey(curve, x); if (pub != null) { ECPublicKey epk = new ECPublicKey(curve, pub); if (!epk.Equals(esk.PublicKey)) { throw new CryptoException( "EC key pair public/private mismatch"); } } return(esk); }
public async Task <List <PreKeyBundle> > GetPreKeys(CancellationToken token, SignalServiceAddress destination, UnidentifiedAccess?unidentifiedAccess, uint deviceIdInteger)// throws IOException { try { string deviceId = deviceIdInteger.ToString(); if (deviceId.Equals("1")) { deviceId = "*"; } string path = string.Format(PREKEY_DEVICE_PATH, destination.E164number, deviceId); if (destination.Relay != null) { path = path + "?relay=" + destination.Relay; } string responseText = await MakeServiceRequestAsync(token, path, "GET", null, unidentifiedAccess); PreKeyResponse response = JsonUtil.FromJson <PreKeyResponse>(responseText); List <PreKeyBundle> bundles = new List <PreKeyBundle>(); foreach (PreKeyResponseItem device in response.Devices) { ECPublicKey preKey = null; ECPublicKey signedPreKey = null; byte[] signedPreKeySignature = null; int preKeyId = -1; int signedPreKeyId = -1; if (device.SignedPreKey != null) { signedPreKey = device.SignedPreKey.PublicKey; signedPreKeyId = (int)device.SignedPreKey.KeyId; signedPreKeySignature = device.SignedPreKey.Signature; } if (device.PreKey != null) { preKeyId = (int)device.PreKey.KeyId; preKey = device.PreKey.PublicKey; } bundles.Add(new PreKeyBundle(device.RegistrationId, device.DeviceId, (uint)preKeyId, preKey, (uint)signedPreKeyId, signedPreKey, signedPreKeySignature, response.IdentityKey)); } return(bundles); } /*catch (JsonUtil.JsonParseException e) * { * throw new IOException(e); * }*/ catch (NotFoundException nfe) { throw new UnregisteredUserException(destination.E164number, nfe); } }
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { ECPublicKey pubKey = (ECPublicKey)value; writer.WriteValue(Base64.EncodeBytesWithoutPadding(pubKey.serialize())); }
public virtual EUID GetEUID(ECPublicKey pubkey) { return(GetEUID(RadixHash.Of(pubkey.Base64Array).ToByteArray())); }
public bool hasReceiverChain(ECPublicKey senderEphemeral) { return getReceiverChain(senderEphemeral) != null; }
public bool hasReceiverChain(ECPublicKey senderEphemeral) { return(getReceiverChain(senderEphemeral) != null); }
public ChainKey getReceiverChainKey(ECPublicKey senderEphemeral) { Pair<Chain, uint> receiverChainAndIndex = getReceiverChain(senderEphemeral); Chain receiverChain = receiverChainAndIndex.first(); if (receiverChain == null) { return null; } else { return new ChainKey(HKDF.createFor(getSessionVersion()), receiverChain.ChainKey.Key.ToByteArray(), receiverChain.ChainKey.Index); } }
public void setUnacknowledgedPreKeyMessage(May <uint> preKeyId, uint signedPreKeyId, ECPublicKey baseKey) { PendingPreKey pending = new PendingPreKey { SignedPreKeyId = (int)signedPreKeyId, BaseKey = ByteString.CopyFrom(baseKey.serialize()) }; if (preKeyId.HasValue) { pending.PreKeyId = preKeyId.ForceGetValue(); } this.sessionStructure.PendingPreKey = pending; }
public bool hasMessageKeys(ECPublicKey senderEphemeral, uint counter) { Pair<Chain, uint> chainAndIndex = getReceiverChain(senderEphemeral); Chain chain = chainAndIndex.first(); if (chain == null) { return false; } IList<Chain.Types.MessageKey> messageKeyList = chain.MessageKeysList; foreach (Chain.Types.MessageKey messageKey in messageKeyList) { if (messageKey.Index == counter) { return true; } } return false; }
/// <summary> /// Verify a card challenge against the card's public key. It is assumed that /// the signature is an EC signature (curve Secp384r1) from a SHA384 hash of the data. /// </summary> /// <param name="data">challenge</param> /// <param name="signature">Signature of the challenge</param> /// <param name="eCPublicKey">ECPublicKey object to verify the signed challenge</param> /// <returns>True if the verification succeeds</returns> public bool VerifyChallenge(byte[] data, byte[] signature, ECPublicKey eCPublicKey) { try { // Offset(dec) ENCODING ASN.1 Syntax // 00 06 05 -- OBJECT_ID LENGTH // 02 2B 81 04 00 22 Secp384r1(1 3 132 0 34) byte[] EncodedParamsCurve = eCPublicKey.ECParams.Value; // Offset(dec) ENCODING ASN.1 Syntax // 00 04 compression byte // 01 { 48 bytes} --X coordinate // 49: { 48 bytes} --Y coordinate byte[] EncodedParamsPoint = eCPublicKey.ECPoint.Value; byte[] KeyParams = new byte[5]; byte[] Secp384r1 = { 0x2B, 0x81, 0x04, 0x00, 0x22 }; byte[] KeyValue_X = new byte[48]; byte[] KeyValue_Y = new byte[48]; Array.Copy(EncodedParamsCurve, 0x02, KeyParams, 0, 5); ECParameters parameters = new ECParameters(); //check if the curve is Secp384r1(1 3 132 0 34) if (System.Collections.StructuralComparisons.StructuralEqualityComparer.Equals(KeyParams, Secp384r1)) { //Fill in parameters named curve: //Create a named curve using the specified Oid object. System.Security.Cryptography.Oid cardP384oid = new Oid("ECDSA_P384"); parameters.Curve = ECCurve.CreateFromOid(cardP384oid); //skip the encoding byte Array.Copy(EncodedParamsPoint, 0x01, KeyValue_X, 0, 48); Array.Copy(EncodedParamsPoint, 0x31, KeyValue_Y, 0, 48); //Fill in parameters public key (Q) System.Security.Cryptography.ECPoint Q; Q.X = KeyValue_X; Q.Y = KeyValue_Y; parameters.Q = Q; } else { //not supported, cannot verify, exit return(false); } ECDsa dsa = ECDsa.Create(parameters); // verify signature. assume that the data was SHA384 hashed. return(dsa.VerifyData(data, signature, HashAlgorithmName.SHA384)); } catch (Exception e) { Console.WriteLine("Error: " + e.Message); return(false); } }
public void setMessageKeys(ECPublicKey senderEphemeral, MessageKeys messageKeys) { Pair<Chain, uint> chainAndIndex = getReceiverChain(senderEphemeral); Chain chain = chainAndIndex.first(); Chain.Types.MessageKey messageKeyStructure = Chain.Types.MessageKey.CreateBuilder() .SetCipherKey(ByteString.CopyFrom(messageKeys.getCipherKey()/*.getEncoded()*/)) .SetMacKey(ByteString.CopyFrom(messageKeys.getMacKey()/*.getEncoded()*/)) .SetIndex(messageKeys.getCounter()) .SetIv(ByteString.CopyFrom(messageKeys.getIv()/*.getIV()*/)) .Build(); Chain.Builder updatedChain = chain.ToBuilder().AddMessageKeys(messageKeyStructure); if (updatedChain.MessageKeysList.Count > MAX_MESSAGE_KEYS) { updatedChain.MessageKeysList.RemoveAt(0); } this.sessionStructure = this.sessionStructure.ToBuilder() .SetReceiverChains((int)chainAndIndex.second(), updatedChain.Build()) // TODO: conv .Build(); }
/// <summary> /// /// </summary> /// <param name="publicKey"></param> /// <param name="message"></param> /// <param name="signature"></param> /// <returns></returns> public byte[] VerifyVrfSignature(ECPublicKey publicKey, byte[] message, byte[] signature) { return(Curve.verifyVrfSignature(publicKey, message, signature)); }
public void setUnacknowledgedPreKeyMessage(May<uint> preKeyId, uint signedPreKeyId, ECPublicKey baseKey) { PendingPreKey.Builder pending = PendingPreKey.CreateBuilder() .SetSignedPreKeyId(signedPreKeyId) .SetBaseKey(ByteString.CopyFrom(baseKey.serialize())); if (preKeyId.HasValue) { pending.SetPreKeyId(preKeyId.ForceGetValue()); } this.sessionStructure = this.sessionStructure.ToBuilder() .SetPendingPreKey(pending.Build()) .Build(); }
public Builder setTheirSignedPreKey(ECPublicKey theirSignedPreKey) { this.theirSignedPreKey = theirSignedPreKey; return(this); }
internal PreKeyEntity(uint keyId, ECPublicKey publicKey) { KeyId = keyId; PublicKey = publicKey; }
public ProvisioningCipher(ECPublicKey theirPublicKey) { this.theirPublicKey = theirPublicKey; }
public Builder setTheirSignedPreKey(ECPublicKey theirSignedPreKey) { this.theirSignedPreKey = theirSignedPreKey; return this; }
public SenderKeyState(uint id, uint iteration, byte[] chainKey, ECPublicKey signatureKey) : this(id, iteration, chainKey, signatureKey, May <ECPrivateKey> .NoValue) { }
private SenderCertificate CreateCertificateFor(ECKeyPair trustRoot, String sender, int deviceId, ECPublicKey identityKey, long expires) { ECKeyPair serverKey = Curve.generateKeyPair(); byte[] serverCertificateBytes = new libsignalmetadata.protobuf.ServerCertificate.Types.Certificate() { Id = 1, Key = ByteString.CopyFrom(serverKey.getPublicKey().serialize()) }.ToByteArray(); byte[] serverCertificateSignature = Curve.calculateSignature(trustRoot.getPrivateKey(), serverCertificateBytes); ServerCertificate serverCertificate = new ServerCertificate(new libsignalmetadata.protobuf.ServerCertificate() { Certificate = ByteString.CopyFrom(serverCertificateBytes), Signature = ByteString.CopyFrom(serverCertificateSignature) }.ToByteArray()); byte[] senderCertificateBytes = new libsignalmetadata.protobuf.SenderCertificate.Types.Certificate { Sender = sender, SenderDevice = (uint)deviceId, IdentityKey = ByteString.CopyFrom(identityKey.serialize()), Expires = (ulong)expires, Signer = libsignalmetadata.protobuf.ServerCertificate.Parser.ParseFrom(serverCertificate.Serialized) }.ToByteArray(); byte[] senderCertificateSignature = Curve.calculateSignature(serverKey.getPrivateKey(), senderCertificateBytes); return(new SenderCertificate(new libsignalmetadata.protobuf.SenderCertificate() { Certificate = ByteString.CopyFrom(senderCertificateBytes), Signature = ByteString.CopyFrom(senderCertificateSignature) }.ToByteArray())); }
public SenderKeyDistributionMessage(uint id, uint iteration, byte[] chainKey, ECPublicKey signatureKey) { byte[] version = { ByteUtil.IntsToByteHighAndLow((int)CURRENT_VERSION, (int)CURRENT_VERSION) }; byte[] protobuf = WhisperProtos.SenderKeyDistributionMessage.CreateBuilder() .SetId(id) .SetIteration(iteration) .SetChainKey(ByteString.CopyFrom(chainKey)) .SetSigningKey(ByteString.CopyFrom(signatureKey.Serialize())) .Build().ToByteArray(); this.id = id; this.iteration = iteration; this.chainKey = chainKey; this.signatureKey = signatureKey; this.serialized = ByteUtil.Combine(version, protobuf); }
private ChainKey getOrCreateChainKey(SessionState sessionState, ECPublicKey theirEphemeral) { try { if (sessionState.hasReceiverChain(theirEphemeral)) { return sessionState.getReceiverChainKey(theirEphemeral); } else { RootKey rootKey = sessionState.getRootKey(); ECKeyPair ourEphemeral = sessionState.getSenderRatchetKeyPair(); Pair<RootKey, ChainKey> receiverChain = rootKey.createChain(theirEphemeral, ourEphemeral); ECKeyPair ourNewEphemeral = Curve.generateKeyPair(); Pair<RootKey, ChainKey> senderChain = receiverChain.first().createChain(theirEphemeral, ourNewEphemeral); sessionState.setRootKey(senderChain.first()); sessionState.addReceiverChain(theirEphemeral, receiverChain.second()); sessionState.setPreviousCounter(Math.Max(sessionState.getSenderChainKey().getIndex() - 1, 0)); sessionState.setSenderChain(ourNewEphemeral, senderChain.second()); return receiverChain.second(); } } catch (InvalidKeyException e) { throw new InvalidMessageException(e); } }
private MessageKeys getOrCreateMessageKeys(SessionState sessionState, ECPublicKey theirEphemeral, ChainKey chainKey, uint counter) { if (chainKey.getIndex() > counter) { if (sessionState.hasMessageKeys(theirEphemeral, counter)) { return sessionState.removeMessageKeys(theirEphemeral, counter); } else { throw new DuplicateMessageException($"Received message with old counter: {chainKey.getIndex()} , {counter}"); } } //Avoiding a uint overflow uint chainKeyIndex = chainKey.getIndex(); if ((counter > chainKeyIndex) && (counter - chainKeyIndex > 2000)) { throw new InvalidMessageException("Over 2000 messages into the future!"); } while (chainKey.getIndex() < counter) { MessageKeys messageKeys = chainKey.getMessageKeys(); sessionState.setMessageKeys(theirEphemeral, messageKeys); chainKey = chainKey.getNextChainKey(); } sessionState.setReceiverChainKey(theirEphemeral, chainKey.getNextChainKey()); return chainKey.getMessageKeys(); }
public void testRootKeyDerivationV2() { byte[] rootKeySeed = { 0x7b, 0xa6, 0xde, 0xbc, 0x2b, 0xc1, 0xbb, 0xf9, 0x1a, 0xbb, 0xc1, 0x36, 0x74, 0x04, 0x17, 0x6c, 0xa6, 0x23, 0x09, 0x5b, 0x7e, 0xc6, 0x6b, 0x45, 0xf6, 0x02, 0xd9, 0x35, 0x38, 0x94, 0x2d, 0xcc }; byte[] alicePublic = { 0x05, 0xee, 0x4f, 0xa6, 0xcd, 0xc0, 0x30, 0xdf, 0x49, 0xec, 0xd0, 0xba, 0x6c, 0xfc, 0xff, 0xb2, 0x33, 0xd3, 0x65, 0xa2, 0x7f, 0xad, 0xbe, 0xff, 0x77, 0xe9, 0x63, 0xfc, 0xb1, 0x62, 0x22, 0xe1, 0x3a }; byte[] alicePrivate = { 0x21, 0x68, 0x22, 0xec, 0x67, 0xeb, 0x38, 0x04, 0x9e, 0xba, 0xe7, 0xb9, 0x39, 0xba, 0xea, 0xeb, 0xb1, 0x51, 0xbb, 0xb3, 0x2d, 0xb8, 0x0f, 0xd3, 0x89, 0x24, 0x5a, 0xc3, 0x7a, 0x94, 0x8e, 0x50 }; byte[] bobPublic = { 0x05, 0xab, 0xb8, 0xeb, 0x29, 0xcc, 0x80, 0xb4, 0x71, 0x09, 0xa2, 0x26, 0x5a, 0xbe, 0x97, 0x98, 0x48, 0x54, 0x06, 0xe3, 0x2d, 0xa2, 0x68, 0x93, 0x4a, 0x95, 0x55, 0xe8, 0x47, 0x57, 0x70, 0x8a, 0x30 }; byte[] nextRoot = { 0xb1, 0x14, 0xf5, 0xde, 0x28, 0x01, 0x19, 0x85, 0xe6, 0xeb, 0xa2, 0x5d, 0x50, 0xe7, 0xec, 0x41, 0xa9, 0xb0, 0x2f, 0x56, 0x93, 0xc5, 0xc7, 0x88, 0xa6, 0x3a, 0x06, 0xd2, 0x12, 0xa2, 0xf7, 0x31 }; byte[] nextChain = { 0x9d, 0x7d, 0x24, 0x69, 0xbc, 0x9a, 0xe5, 0x3e, 0xe9, 0x80, 0x5a, 0xa3, 0x26, 0x4d, 0x24, 0x99, 0xa3, 0xac, 0xe8, 0x0f, 0x4c, 0xca, 0xe2, 0xda, 0x13, 0x43, 0x0c, 0x5c, 0x55, 0xb5, 0xca, 0x5f }; ECPublicKey alicePublicKey = Curve.decodePoint(alicePublic, 0); ECPrivateKey alicePrivateKey = Curve.decodePrivatePoint(alicePrivate); ECKeyPair aliceKeyPair = new ECKeyPair(alicePublicKey, alicePrivateKey); ECPublicKey bobPublicKey = Curve.decodePoint(bobPublic, 0); RootKey rootKey = new RootKey(HKDF.createFor(2), rootKeySeed); Pair <RootKey, ChainKey> rootKeyChainKeyPair = rootKey.createChain(bobPublicKey, aliceKeyPair); RootKey nextRootKey = rootKeyChainKeyPair.first(); ChainKey nextChainKey = rootKeyChainKeyPair.second(); CollectionAssert.AreEqual(rootKey.getKeyBytes(), rootKeySeed); CollectionAssert.AreEqual(nextRootKey.getKeyBytes(), nextRoot); CollectionAssert.AreEqual(nextChainKey.getKey(), nextChain); }
public Builder setTheirRatchetKey(ECPublicKey theirRatchetKey) { this.theirRatchetKey = theirRatchetKey; return this; }
public Builder setTheirBaseKey(ECPublicKey theirBaseKey) { this.theirBaseKey = theirBaseKey; return this; }
public void setUnacknowledgedPreKeyMessage(May <uint> preKeyId, uint signedPreKeyId, ECPublicKey baseKey) { PendingPreKey.Builder pending = PendingPreKey.CreateBuilder() .SetSignedPreKeyId(signedPreKeyId) .SetBaseKey(ByteString.CopyFrom(baseKey.serialize())); if (preKeyId.HasValue) { pending.SetPreKeyId(preKeyId.ForceGetValue()); } this.sessionStructure = this.sessionStructure.ToBuilder() .SetPendingPreKey(pending.Build()) .Build(); }
public static byte[] calculateAgreement(ECPublicKey publicKey, ECPrivateKey privateKey) { if (publicKey.getType() != privateKey.getType()) { throw new InvalidKeyException("Public and private keys must be of the same type!"); } if (publicKey.getType() == DJB_TYPE) { return Curve25519.getInstance(Curve25519ProviderType.BEST) .calculateAgreement(((DjbECPublicKey)publicKey).getPublicKey(), ((DjbECPrivateKey)privateKey).getPrivateKey()); } else { throw new InvalidKeyException("Unknown type: " + publicKey.getType()); } }