예제 #1
0
        protected virtual byte[] GenerateOtherSecret(int pskLength)
        {
            if (this.mKeyExchange == KeyExchangeAlgorithm.DHE_PSK)
            {
                if (mDHAgreePrivateKey != null)
                {
                    return(TlsDHUtilities.CalculateDHBasicAgreement(mDHAgreePublicKey, mDHAgreePrivateKey));
                }

                throw new TlsFatalAlert(AlertDescription.internal_error);
            }

            if (this.mKeyExchange == KeyExchangeAlgorithm.ECDHE_PSK)
            {
                if (mECAgreePrivateKey != null)
                {
                    return(TlsEccUtilities.CalculateECDHBasicAgreement(mECAgreePublicKey, mECAgreePrivateKey));
                }

                throw new TlsFatalAlert(AlertDescription.internal_error);
            }

            if (this.mKeyExchange == KeyExchangeAlgorithm.RSA_PSK)
            {
                return(this.mPremasterSecret);
            }

            return(new byte[pskLength]);
        }
예제 #2
0
        protected virtual DHParameters ValidateDHParameters(DHParameters parameters)
        {
            if (parameters.P.BitLength < MinimumPrimeBits)
            {
                throw new TlsFatalAlert(AlertDescription.insufficient_security);
            }

            return(TlsDHUtilities.ValidateDHParameters(parameters));
        }
예제 #3
0
        /**
         * Parse a {@link ServerDHParams} from a {@link Stream}.
         *
         * @param input
         *            the {@link Stream} to parse from.
         * @return a {@link ServerDHParams} object.
         * @throws IOException
         */
        public static ServerDHParams Parse(Stream input)
        {
            BigInteger p  = TlsDHUtilities.ReadDHParameter(input);
            BigInteger g  = TlsDHUtilities.ReadDHParameter(input);
            BigInteger Ys = TlsDHUtilities.ReadDHParameter(input);

            return(new ServerDHParams(
                       TlsDHUtilities.ValidateDHPublicKey(new DHPublicKeyParameters(Ys, new DHParameters(p, g)))));
        }
예제 #4
0
        /**
         * Encode this {@link ServerDHParams} to a {@link Stream}.
         *
         * @param output
         *            the {@link Stream} to encode to.
         * @throws IOException
         */
        public virtual void Encode(Stream output)
        {
            DHParameters dhParameters = mPublicKey.Parameters;
            BigInteger   Ys           = mPublicKey.Y;

            TlsDHUtilities.WriteDHParameter(dhParameters.P, output);
            TlsDHUtilities.WriteDHParameter(dhParameters.G, output);
            TlsDHUtilities.WriteDHParameter(Ys, output);
        }
예제 #5
0
        public override void ProcessClientKeyExchange(Stream input)
        {
            if (mDHAgreePublicKey != null)
            {
                // For dss_fixed_dh and rsa_fixed_dh, the key arrived in the client certificate
                return;
            }

            BigInteger Yc = TlsDHUtilities.ReadDHParameter(input);

            this.mDHAgreePublicKey = TlsDHUtilities.ValidateDHPublicKey(new DHPublicKeyParameters(Yc, mDHParameters));
        }
예제 #6
0
 public override void GenerateClientKeyExchange(Stream output)
 {
     /*
      * RFC 2246 7.4.7.2 If the client certificate already contains a suitable Diffie-Hellman
      * key, then Yc is implicit and does not need to be sent again. In this case, the Client Key
      * Exchange message will be sent, but will be empty.
      */
     if (mAgreementCredentials == null)
     {
         this.mDHAgreePrivateKey = TlsDHUtilities.GenerateEphemeralClientKeyExchange(mContext.SecureRandom,
                                                                                     mDHParameters, output);
     }
 }
예제 #7
0
        public override byte[] GeneratePremasterSecret()
        {
            if (mAgreementCredentials != null)
            {
                return(mAgreementCredentials.GenerateAgreement(mDHAgreePublicKey));
            }

            if (mDHAgreePrivateKey != null)
            {
                return(TlsDHUtilities.CalculateDHBasicAgreement(mDHAgreePublicKey, mDHAgreePrivateKey));
            }

            throw new TlsFatalAlert(AlertDescription.internal_error);
        }
예제 #8
0
        public override void ProcessServerCertificate(Certificate serverCertificate)
        {
            if (serverCertificate.IsEmpty)
            {
                throw new TlsFatalAlert(AlertDescription.bad_certificate);
            }

            X509CertificateStructure x509Cert = serverCertificate.GetCertificateAt(0);

            SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo;

            try
            {
                this.mServerPublicKey = PublicKeyFactory.CreateKey(keyInfo);
            }
            catch (Exception e)
            {
                throw new TlsFatalAlert(AlertDescription.unsupported_certificate, e);
            }

            if (mTlsSigner == null)
            {
                try
                {
                    this.mDHAgreePublicKey = TlsDHUtilities.ValidateDHPublicKey((DHPublicKeyParameters)this.mServerPublicKey);
                    this.mDHParameters     = ValidateDHParameters(mDHAgreePublicKey.Parameters);
                }
                catch (InvalidCastException e)
                {
                    throw new TlsFatalAlert(AlertDescription.certificate_unknown, e);
                }

                TlsUtilities.ValidateKeyUsage(x509Cert, KeyUsage.KeyAgreement);
            }
            else
            {
                if (!mTlsSigner.IsValidPublicKey(this.mServerPublicKey))
                {
                    throw new TlsFatalAlert(AlertDescription.certificate_unknown);
                }

                TlsUtilities.ValidateKeyUsage(x509Cert, KeyUsage.DigitalSignature);
            }

            base.ProcessServerCertificate(serverCertificate);
        }
예제 #9
0
        public override void ProcessClientKeyExchange(Stream input)
        {
            byte[] psk_identity = TlsUtilities.ReadOpaque16(input);

            this.mPsk = mPskIdentityManager.GetPsk(psk_identity);
            if (mPsk == null)
            {
                throw new TlsFatalAlert(AlertDescription.unknown_psk_identity);
            }

            mContext.SecurityParameters.pskIdentity = psk_identity;

            if (this.mKeyExchange == KeyExchangeAlgorithm.DHE_PSK)
            {
                BigInteger Yc = TlsDHUtilities.ReadDHParameter(input);

                this.mDHAgreePublicKey = TlsDHUtilities.ValidateDHPublicKey(new DHPublicKeyParameters(Yc, mDHParameters));
            }
            else if (this.mKeyExchange == KeyExchangeAlgorithm.ECDHE_PSK)
            {
                byte[] point = TlsUtilities.ReadOpaque8(input);

                ECDomainParameters curve_params = this.mECAgreePrivateKey.Parameters;

                this.mECAgreePublicKey = TlsEccUtilities.ValidateECPublicKey(TlsEccUtilities.DeserializeECPublicKey(
                                                                                 mServerECPointFormats, curve_params, point));
            }
            else if (this.mKeyExchange == KeyExchangeAlgorithm.RSA_PSK)
            {
                byte[] encryptedPreMasterSecret;
                if (TlsUtilities.IsSsl(mContext))
                {
                    // TODO Do any SSLv3 clients actually include the length?
                    encryptedPreMasterSecret = Streams.ReadAll(input);
                }
                else
                {
                    encryptedPreMasterSecret = TlsUtilities.ReadOpaque16(input);
                }

                this.mPremasterSecret = mServerCredentials.DecryptPreMasterSecret(encryptedPreMasterSecret);
            }
        }
예제 #10
0
        public override void GenerateClientKeyExchange(Stream output)
        {
            if (mPskIdentityHint == null)
            {
                mPskIdentity.SkipIdentityHint();
            }
            else
            {
                mPskIdentity.NotifyIdentityHint(mPskIdentityHint);
            }

            byte[] psk_identity = mPskIdentity.GetPskIdentity();
            if (psk_identity == null)
            {
                throw new TlsFatalAlert(AlertDescription.internal_error);
            }

            this.mPsk = mPskIdentity.GetPsk();
            if (mPsk == null)
            {
                throw new TlsFatalAlert(AlertDescription.internal_error);
            }

            TlsUtilities.WriteOpaque16(psk_identity, output);

            mContext.SecurityParameters.pskIdentity = psk_identity;

            if (this.mKeyExchange == KeyExchangeAlgorithm.DHE_PSK)
            {
                this.mDHAgreePrivateKey = TlsDHUtilities.GenerateEphemeralClientKeyExchange(mContext.SecureRandom,
                                                                                            mDHParameters, output);
            }
            else if (this.mKeyExchange == KeyExchangeAlgorithm.ECDHE_PSK)
            {
                this.mECAgreePrivateKey = TlsEccUtilities.GenerateEphemeralClientKeyExchange(mContext.SecureRandom,
                                                                                             mServerECPointFormats, mECAgreePublicKey.Parameters, output);
            }
            else if (this.mKeyExchange == KeyExchangeAlgorithm.RSA_PSK)
            {
                this.mPremasterSecret = TlsRsaUtilities.GenerateEncryptedPreMasterSecret(mContext,
                                                                                         this.mRsaServerPublicKey, output);
            }
        }
예제 #11
0
        public override void ProcessServerKeyExchange(Stream input)
        {
            this.mPskIdentityHint = TlsUtilities.ReadOpaque16(input);

            if (this.mKeyExchange == KeyExchangeAlgorithm.DHE_PSK)
            {
                ServerDHParams serverDHParams = ServerDHParams.Parse(input);

                this.mDHAgreePublicKey = TlsDHUtilities.ValidateDHPublicKey(serverDHParams.PublicKey);
                this.mDHParameters     = mDHAgreePublicKey.Parameters;
            }
            else if (this.mKeyExchange == KeyExchangeAlgorithm.ECDHE_PSK)
            {
                ECDomainParameters ecParams = TlsEccUtilities.ReadECParameters(mNamedCurves, mClientECPointFormats, input);

                byte[] point = TlsUtilities.ReadOpaque8(input);

                this.mECAgreePublicKey = TlsEccUtilities.ValidateECPublicKey(TlsEccUtilities.DeserializeECPublicKey(
                                                                                 mClientECPointFormats, ecParams, point));
            }
        }
예제 #12
0
        public override void ProcessServerKeyExchange(Stream input)
        {
            SecurityParameters securityParameters = mContext.SecurityParameters;

            SignerInputBuffer buf   = new SignerInputBuffer();
            Stream            teeIn = new TeeInputStream(input, buf);

            ServerDHParams dhParams = ServerDHParams.Parse(teeIn);

            DigitallySigned signed_params = ParseSignature(input);

            ISigner signer = InitVerifyer(mTlsSigner, signed_params.Algorithm, securityParameters);

            buf.UpdateSigner(signer);
            if (!signer.VerifySignature(signed_params.Signature))
            {
                throw new TlsFatalAlert(AlertDescription.decrypt_error);
            }

            this.mDHAgreePublicKey = TlsDHUtilities.ValidateDHPublicKey(dhParams.PublicKey);
            this.mDHParameters     = ValidateDHParameters(mDHAgreePublicKey.Parameters);
        }
예제 #13
0
        public override byte[] GenerateServerKeyExchange()
        {
            this.mPskIdentityHint = mPskIdentityManager.GetHint();

            if (this.mPskIdentityHint == null && !RequiresServerKeyExchange)
            {
                return(null);
            }

            MemoryStream buf = new MemoryStream();

            if (this.mPskIdentityHint == null)
            {
                TlsUtilities.WriteOpaque16(TlsUtilities.EmptyBytes, buf);
            }
            else
            {
                TlsUtilities.WriteOpaque16(this.mPskIdentityHint, buf);
            }

            if (this.mKeyExchange == KeyExchangeAlgorithm.DHE_PSK)
            {
                if (this.mDHParameters == null)
                {
                    throw new TlsFatalAlert(AlertDescription.internal_error);
                }

                this.mDHAgreePrivateKey = TlsDHUtilities.GenerateEphemeralServerKeyExchange(mContext.SecureRandom,
                                                                                            this.mDHParameters, buf);
            }
            else if (this.mKeyExchange == KeyExchangeAlgorithm.ECDHE_PSK)
            {
                this.mECAgreePrivateKey = TlsEccUtilities.GenerateEphemeralServerKeyExchange(mContext.SecureRandom,
                                                                                             mNamedCurves, mClientECPointFormats, buf);
            }

            return(buf.ToArray());
        }
예제 #14
0
        public override byte[] GenerateServerKeyExchange()
        {
            if (this.mDHParameters == null)
            {
                throw new TlsFatalAlert(AlertDescription.internal_error);
            }

            DigestInputBuffer buf = new DigestInputBuffer();

            this.mDHAgreePrivateKey = TlsDHUtilities.GenerateEphemeralServerKeyExchange(mContext.SecureRandom,
                                                                                        this.mDHParameters, buf);

            /*
             * RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2
             */
            SignatureAndHashAlgorithm signatureAndHashAlgorithm = TlsUtilities.GetSignatureAndHashAlgorithm(
                mContext, mServerCredentials);

            IDigest d = TlsUtilities.CreateHash(signatureAndHashAlgorithm);

            SecurityParameters securityParameters = mContext.SecurityParameters;

            d.BlockUpdate(securityParameters.clientRandom, 0, securityParameters.clientRandom.Length);
            d.BlockUpdate(securityParameters.serverRandom, 0, securityParameters.serverRandom.Length);
            buf.UpdateDigest(d);

            byte[] hash = DigestUtilities.DoFinal(d);

            byte[] signature = mServerCredentials.GenerateCertificateSignature(hash);

            DigitallySigned signed_params = new DigitallySigned(signatureAndHashAlgorithm, signature);

            signed_params.Encode(buf);

            return(buf.ToArray());
        }