public virtual void ProcessServerCertificate(Certificate serverCertificate)
		{
			X509CertificateStructure x509Cert = serverCertificate.certs[0];
			SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo;

			try
			{
				this.serverPublicKey = PublicKeyFactory.CreateKey(keyInfo);
			}
//			catch (RuntimeException)
			catch (Exception)
			{
				throw new TlsFatalAlert(AlertDescription.unsupported_certificate);
			}

			// Sanity check the PublicKeyFactory
			if (this.serverPublicKey.IsPrivate)
			{
				throw new TlsFatalAlert(AlertDescription.internal_error);
			}

			this.rsaServerPublicKey = ValidateRsaPublicKey((RsaKeyParameters)this.serverPublicKey);

			TlsUtilities.ValidateKeyUsage(x509Cert, KeyUsage.KeyEncipherment);

			// TODO
			/*
			* Perform various checks per RFC2246 7.4.2: "Unless otherwise specified, the
			* signing algorithm for the certificate must be the same as the algorithm for the
			* certificate key."
			*/
		}
		public RsaBlindingParameters(
			RsaKeyParameters	publicKey,
			BigInteger			blindingFactor)
		{
			if (publicKey.IsPrivate)
				throw new ArgumentException("RSA parameters should be for a public key");

			this.publicKey = publicKey;
			this.blindingFactor = blindingFactor;
		}
        public static AsymmetricCipherKeyPair GetRsaKeyPair(RSAParameters rp)
        {
            var modulus = new BigInteger(1, rp.Modulus);
            var pubExp = new BigInteger(1, rp.Exponent);

            var pubKey = new RsaKeyParameters(false, modulus, pubExp);

            var privKey = new RsaPrivateCrtKeyParameters(modulus, pubExp, new BigInteger(1, rp.D), new BigInteger(1, rp.P), new BigInteger(1, rp.Q),
                new BigInteger(1, rp.DP), new BigInteger(1, rp.DQ), new BigInteger(1, rp.InverseQ));

            return new AsymmetricCipherKeyPair(pubKey, privKey);
        }
		/**
		* initialise the RSA engine.
		*
		* @param forEncryption true if we are encrypting, false otherwise.
		* @param param the necessary RSA key parameters.
		*/
		public void Init(
			bool				forEncryption,
			ICipherParameters	parameters)
		{
			if (parameters is ParametersWithRandom)
			{
				parameters = ((ParametersWithRandom) parameters).Parameters;
			}

			if (!(parameters is RsaKeyParameters))
				throw new InvalidKeyException("Not an RSA key");

			this.key = (RsaKeyParameters) parameters;
			this.forEncryption = forEncryption;
			this.bitSize = key.Modulus.BitLength;
		}
		/**
		* Initialise the factor generator
		*
		* @param param the necessary RSA key parameters.
		*/
		public void Init(
			ICipherParameters param)
		{
			if (param is ParametersWithRandom)
			{
				ParametersWithRandom rParam = (ParametersWithRandom)param;

				key = (RsaKeyParameters)rParam.Parameters;
				random = rParam.Random;
			}
			else
			{
				key = (RsaKeyParameters)param;
				random = new SecureRandom();
			}

			if (key.IsPrivate)
				throw new ArgumentException("generator requires RSA public key");
		}
		/**
		 * initialise the RSA engine.
		 *
		 * @param forEncryption true if we are encrypting, false otherwise.
		 * @param param the necessary RSA key parameters.
		 */
		public void Init(
			bool				forEncryption,
			ICipherParameters	param)
		{
			core.Init(forEncryption, param);

			if (param is ParametersWithRandom)
			{
				ParametersWithRandom rParam = (ParametersWithRandom)param;

				key = (RsaKeyParameters)rParam.Parameters;
				random = rParam.Random;
			}
			else
			{
				key = (RsaKeyParameters)param;
				random = new SecureRandom();
			}
		}
 public static RSAParameters ToRSAParameters(RsaKeyParameters rsaKey)
 {
     var rp = new RSAParameters();
     rp.Modulus = rsaKey.Modulus.ToByteArrayUnsigned();
     if (rsaKey.IsPrivate)
     {
         rp.D = rsaKey.Exponent.ToByteArrayUnsigned();
     }
     else
     {
         rp.Exponent = rsaKey.Exponent.ToByteArrayUnsigned();
     }
     return rp;
 }
 public static RSA ToRSA(RsaKeyParameters rsaKey)
 {
     RSAParameters rp = ToRSAParameters(rsaKey);
     var rsaCsp = new RSACryptoServiceProvider();
     rsaCsp.ImportParameters(rp);
     return rsaCsp;
 }
Example #9
0
		/**
		* Read a Key Pair
		*/
		private object ReadPrivateKey(PemObject pemObject)
		{
			//
			// extract the key
			//
			Debug.Assert(pemObject.Type.EndsWith("PRIVATE KEY"));

			string type = pemObject.Type.Substring(0, pemObject.Type.Length - "PRIVATE KEY".Length).Trim();
			byte[] keyBytes = pemObject.Content;

			IDictionary fields = Platform.CreateHashtable();
			foreach (PemHeader header in pemObject.Headers)
			{
				fields[header.Name] = header.Value;
			}

			string procType = (string) fields["Proc-Type"];

			if (procType == "4,ENCRYPTED")
			{
				if (pFinder == null)
					throw new PasswordException("No password finder specified, but a password is required");

				char[] password = pFinder.GetPassword();

				if (password == null)
					throw new PasswordException("Password is null, but a password is required");

				string dekInfo = (string) fields["DEK-Info"];
				string[] tknz = dekInfo.Split(',');

				string dekAlgName = tknz[0].Trim();
				byte[] iv = Hex.Decode(tknz[1].Trim());

				keyBytes = PemUtilities.Crypt(false, keyBytes, password, dekAlgName, iv);
			}

			try
			{
				AsymmetricKeyParameter pubSpec, privSpec;
				Asn1Sequence seq = (Asn1Sequence) Asn1Object.FromByteArray(keyBytes);

				switch (type)
				{
					case "RSA":
					{
						if (seq.Count != 9)
							throw new PemException("malformed sequence in RSA private key");

						RsaPrivateKeyStructure rsa = new RsaPrivateKeyStructure(seq);

						pubSpec = new RsaKeyParameters(false, rsa.Modulus, rsa.PublicExponent);
						privSpec = new RsaPrivateCrtKeyParameters(
							rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent,
							rsa.Prime1, rsa.Prime2, rsa.Exponent1, rsa.Exponent2,
							rsa.Coefficient);

						break;
					}

					case "DSA":
					{
						if (seq.Count != 6)
							throw new PemException("malformed sequence in DSA private key");

						// TODO Create an ASN1 object somewhere for this?
						//DerInteger v = (DerInteger)seq[0];
						DerInteger p = (DerInteger)seq[1];
						DerInteger q = (DerInteger)seq[2];
						DerInteger g = (DerInteger)seq[3];
						DerInteger y = (DerInteger)seq[4];
						DerInteger x = (DerInteger)seq[5];

						DsaParameters parameters = new DsaParameters(p.Value, q.Value, g.Value);

						privSpec = new DsaPrivateKeyParameters(x.Value, parameters);
						pubSpec = new DsaPublicKeyParameters(y.Value, parameters);

						break;
					}

					case "EC":
					{
						ECPrivateKeyStructure pKey = new ECPrivateKeyStructure(seq);
						AlgorithmIdentifier algId = new AlgorithmIdentifier(
							X9ObjectIdentifiers.IdECPublicKey, pKey.GetParameters());

						PrivateKeyInfo privInfo = new PrivateKeyInfo(algId, pKey.ToAsn1Object());

						// TODO Are the keys returned here ECDSA, as Java version forces?
						privSpec = PrivateKeyFactory.CreateKey(privInfo);

						DerBitString pubKey = pKey.GetPublicKey();
						if (pubKey != null)
						{
							SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo(algId, pubKey.GetBytes());

							// TODO Are the keys returned here ECDSA, as Java version forces?
							pubSpec = PublicKeyFactory.CreateKey(pubInfo);
						}
						else
						{
							pubSpec = ECKeyPairGenerator.GetCorrespondingPublicKey(
								(ECPrivateKeyParameters)privSpec);
						}

						break;
					}

					case "ENCRYPTED":
					{
						char[] password = pFinder.GetPassword();

						if (password == null)
							throw new PasswordException("Password is null, but a password is required");

						return PrivateKeyFactory.DecryptKey(password, EncryptedPrivateKeyInfo.GetInstance(seq));
					}

					case "":
					{
						return PrivateKeyFactory.CreateKey(PrivateKeyInfo.GetInstance(seq));
					}

					default:
						throw new ArgumentException("Unknown key type: " + type, "type");
				}

				return new AsymmetricCipherKeyPair(pubSpec, privSpec);
			}
			catch (IOException e)
			{
				throw e;
			}
			catch (Exception e)
			{
				throw new PemException(
					"problem creating " + type + " private key: " + e.ToString());
			}
		}
    	// Would be needed to process RSA_EXPORT server key exchange
//	    protected virtual void ProcessRsaServerKeyExchange(Stream input, ISigner signer)
//	    {
//	        Stream sigIn = input;
//	        if (signer != null)
//	        {
//	            sigIn = new SignerStream(input, signer, null);
//	        }
//
//	        byte[] modulusBytes = TlsUtilities.ReadOpaque16(sigIn);
//	        byte[] exponentBytes = TlsUtilities.ReadOpaque16(sigIn);
//
//	        if (signer != null)
//	        {
//	            byte[] sigByte = TlsUtilities.ReadOpaque16(input);
//
//	            if (!signer.VerifySignature(sigByte))
//	            {
//	                handler.FailWithError(AlertLevel.fatal, AlertDescription.bad_certificate);
//	            }
//	        }
//
//	        BigInteger modulus = new BigInteger(1, modulusBytes);
//	        BigInteger exponent = new BigInteger(1, exponentBytes);
//
//	        this.rsaServerPublicKey = ValidateRSAPublicKey(new RsaKeyParameters(false, modulus, exponent));
//	    }

        protected virtual RsaKeyParameters ValidateRsaPublicKey(RsaKeyParameters key)
		{
			// TODO What is the minimum bit length required?
//			key.Modulus.BitLength;

			if (!key.Exponent.IsProbablePrime(2))
			{
				throw new TlsFatalAlert(AlertDescription.illegal_parameter);
			}

			return key;
		}