Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 4
0
        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();
            }
        }
Ejemplo n.º 5
0
        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);
        }
Ejemplo n.º 6
0
 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());
     }
 }
Ejemplo n.º 7
0
 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);
        }
Ejemplo n.º 9
0
        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!");
            }
        }
Ejemplo n.º 11
0
        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);
            }
        }
Ejemplo n.º 14
0
        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;
        }
Ejemplo n.º 15
0
		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();
		}
Ejemplo n.º 16
0
			public UnacknowledgedPreKeyMessageItems(May<uint> preKeyId,
													uint signedPreKeyId,
													ECPublicKey baseKey)
			{
				this.preKeyId = preKeyId;
				this.signedPreKeyId = signedPreKeyId;
				this.baseKey = baseKey;
			}
Ejemplo n.º 17
0
		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
			}
		}
Ejemplo n.º 18
0
		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);
 }
Ejemplo n.º 20
0
		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;
		}
Ejemplo n.º 21
0
 public IdentityKey(byte[] bytes, int offset)
 {
     publicKey = Curve.decodePoint(bytes, offset);
 }
Ejemplo n.º 22
0
        public static CertificateValidator GetCertificateValidator()
        {
            ECPublicKey unidentifiedSenderTrustRoot = Curve.decodePoint(Base64.Decode(UNIDENTIFIED_SENDER_TRUST_ROOT), 0);

            return(new CertificateValidator(unidentifiedSenderTrustRoot));
        }
Ejemplo n.º 23
0
 public Builder setTheirBaseKey(ECPublicKey theirBaseKey)
 {
     this.theirBaseKey = theirBaseKey;
     return(this);
 }
Ejemplo n.º 24
0
 public IdentityKey(ECPublicKey publicKey)
 {
     this.publicKey = publicKey;
 }
Ejemplo n.º 25
0
 public bool VerifySecuritySignature(ECPublicKey publicKey, byte[] signature)
 {
     return(VerifySignature(publicKey, securityString, signature));
 }
Ejemplo n.º 26
0
 public bool VerifySignature(ECPublicKey publicKey, string data, byte[] signature)
 {
     return(VerifySignature(publicKey, StringToBytes(data), signature));
 }
Ejemplo n.º 27
0
 public ECKeyPair(ECPublicKey publicKey, ECPrivateKey privateKey)
 {
     this.publicKey  = publicKey;
     this.privateKey = privateKey;
 }
Ejemplo n.º 28
0
        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);
            }
        }
Ejemplo n.º 29
0
 private static bool IsAlice(ECPublicKey ourKey, ECPublicKey theirKey)
 {
     return(ourKey.CompareTo(theirKey) < 0);
 }
Ejemplo n.º 30
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);
            }
        }
Ejemplo n.º 32
0
            public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
            {
                ECPublicKey pubKey = (ECPublicKey)value;

                writer.WriteValue(Base64.EncodeBytesWithoutPadding(pubKey.serialize()));
            }
Ejemplo n.º 33
0
 public virtual EUID GetEUID(ECPublicKey pubkey)
 {
     return(GetEUID(RadixHash.Of(pubkey.Base64Array).ToByteArray()));
 }
Ejemplo n.º 34
0
		public bool hasReceiverChain(ECPublicKey senderEphemeral)
		{
			return getReceiverChain(senderEphemeral) != null;
		}
 public bool hasReceiverChain(ECPublicKey senderEphemeral)
 {
     return(getReceiverChain(senderEphemeral) != null);
 }
Ejemplo n.º 36
0
		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;
        }
Ejemplo n.º 38
0
		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;
		}
Ejemplo n.º 39
0
        /// <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);
            }
        }
Ejemplo n.º 40
0
		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();
		}
Ejemplo n.º 41
0
 /// <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));
 }
Ejemplo n.º 42
0
		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();
		}
Ejemplo n.º 43
0
 public Builder setTheirSignedPreKey(ECPublicKey theirSignedPreKey)
 {
     this.theirSignedPreKey = theirSignedPreKey;
     return(this);
 }
Ejemplo n.º 44
0
 internal PreKeyEntity(uint keyId, ECPublicKey publicKey)
 {
     KeyId     = keyId;
     PublicKey = publicKey;
 }
Ejemplo n.º 45
0
 public ProvisioningCipher(ECPublicKey theirPublicKey)
 {
     this.theirPublicKey = theirPublicKey;
 }
 public Builder setTheirSignedPreKey(ECPublicKey theirSignedPreKey)
 {
     this.theirSignedPreKey = theirSignedPreKey;
     return this;
 }
Ejemplo n.º 47
0
 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);
        }
Ejemplo n.º 50
0
		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);
			}
		}
Ejemplo n.º 51
0
		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();
		}
Ejemplo n.º 52
0
        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;
 }
Ejemplo n.º 55
0
        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();
        }
Ejemplo n.º 56
-1
        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());
            }
        }