/// <summary>
        /// Generate an enveloped object that contains a CMS Enveloped Data
        /// object using the passed in key generator.
        /// </summary>
        private CmsEnvelopedData Generate(
            CmsProcessable content,
            string encryptionOid,
            CipherKeyGenerator keyGen)
        {
            AlgorithmIdentifier encAlgId = null;
            KeyParameter        encKey;
            Asn1OctetString     encContent;

            try
            {
                byte[] encKeyBytes = keyGen.GenerateKey();
                encKey = ParameterUtilities.CreateKeyParameter(encryptionOid, encKeyBytes);

                Asn1Encodable asn1Params = GenerateAsn1Parameters(encryptionOid, encKeyBytes);

                ICipherParameters cipherParameters;
                encAlgId = GetAlgorithmIdentifier(
                    encryptionOid, encKey, asn1Params, out cipherParameters);

                IBufferedCipher cipher = CipherUtilities.GetCipher(encryptionOid);
                cipher.Init(true, new ParametersWithRandom(cipherParameters, rand));

                MemoryStream bOut = new MemoryStream();
                CipherStream cOut = new CipherStream(bOut, null, cipher);

                content.Write(cOut);

                Platform.Dispose(cOut);

                encContent = new BerOctetString(bOut.ToArray());
            }
            catch (SecurityUtilityException e)
            {
                throw new CmsException("couldn't create cipher.", e);
            }
            catch (InvalidKeyException e)
            {
                throw new CmsException("key invalid in message.", e);
            }
            catch (IOException e)
            {
                throw new CmsException("exception decoding algorithm parameters.", e);
            }


            Asn1EncodableVector recipientInfos = new Asn1EncodableVector();

            foreach (RecipientInfoGenerator rig in recipientInfoGenerators)
            {
                try
                {
                    recipientInfos.Add(rig.Generate(encKey, rand));
                }
                catch (InvalidKeyException e)
                {
                    throw new CmsException("key inappropriate for algorithm.", e);
                }
                catch (GeneralSecurityException e)
                {
                    throw new CmsException("error making encrypted content.", e);
                }
            }

            EncryptedContentInfo eci = new EncryptedContentInfo(
                CmsObjectIdentifiers.Data,
                encAlgId,
                encContent);

            Asn1Set unprotectedAttrSet = null;

            if (unprotectedAttributeGenerator != null)
            {
                AttributeTable attrTable = unprotectedAttributeGenerator.GetAttributes(Platform.CreateHashtable());

                unprotectedAttrSet = new BerSet(attrTable.ToAsn1EncodableVector());
            }

            ContentInfo contentInfo = new ContentInfo(
                CmsObjectIdentifiers.EnvelopedData,
                new EnvelopedData(null, new DerSet(recipientInfos), eci, unprotectedAttrSet));

            return(new CmsEnvelopedData(contentInfo));
        }
        public async Task <Optional <string> > GetSecretAsync(string name, string version = null, Dictionary <string, string> encryptionContext = null, bool throwOnInvalidCipherTextException = true)
        {
            CredstashItem item;

            if (version == null)
            {
                var response = await _amazonDynamoDb.QueryAsync(new QueryRequest()
                {
                    TableName        = Options.Table,
                    Limit            = 1,
                    ScanIndexForward = false,
                    ConsistentRead   = true,
                    KeyConditions    = new Dictionary <string, Condition>()
                    {
                        {
                            "name", new Condition()
                            {
                                ComparisonOperator = ComparisonOperator.EQ,
                                AttributeValueList = new List <AttributeValue>()
                                {
                                    new AttributeValue(name)
                                }
                            }
                        }
                    }
                }).ConfigureAwait(false);

                item = CredstashItem.From(response.Items.FirstOrDefault());
            }
            else
            {
                var response = await _amazonDynamoDb.GetItemAsync(new GetItemRequest()
                {
                    TableName = Options.Table,
                    Key       = new Dictionary <string, AttributeValue>()
                    {
                        { "name", new AttributeValue(name) },
                        { "version", new AttributeValue(version) },
                    }
                }).ConfigureAwait(false);

                item = CredstashItem.From(response.Item);
            }

            if (item == null)
            {
                return(null);
            }

            DecryptResponse decryptResponse;

            try
            {
                decryptResponse = await _amazonKeyManagementService.DecryptAsync(new DecryptRequest()
                {
                    CiphertextBlob    = new MemoryStream(Convert.FromBase64String(item.Key)),
                    EncryptionContext = encryptionContext
                }).ConfigureAwait(false);
            }
            catch (InvalidCiphertextException e)
            {
                if (throwOnInvalidCipherTextException)
                {
                    throw new CredstashException("Could not decrypt hmac key with KMS. The credential may " +
                                                 "require that an encryption context be provided to decrypt " +
                                                 "it.", e);
                }
                return(new Optional <string>());
            }
            catch (Exception e)
            {
                throw new CredstashException("Decryption error", e);
            }
            var bytes   = decryptResponse.Plaintext.ToArray();
            var key     = new byte[32];
            var hmacKey = new byte[32];

            Buffer.BlockCopy(bytes, 0, key, 0, 32);
            Buffer.BlockCopy(bytes, 32, hmacKey, 0, 32);

            var contents = Convert.FromBase64String(item.Contents);

            var hmac   = new HMACSHA256(hmacKey);
            var result = hmac.ComputeHash(contents);

            if (!result.ToHexString().Equals(item.Hmac))
            {
                throw new CredstashException($"HMAC Failure for {item.Name} v{item.Version}");
            }

            IBufferedCipher cipher = CipherUtilities.GetCipher("AES/CTR/NoPadding");

            cipher.Init(false, new ParametersWithIV(ParameterUtilities.CreateKeyParameter("AES", key), _initializationVector));
            byte[] plaintext = cipher.DoFinal(contents);
            return(Encoding.UTF8.GetString(plaintext));
        }
        /// <inheritdoc/>
        protected override async Task OnOpenAsync(CancellationToken token = default(CancellationToken))
        {
            this.logger?.LogInformation($"Opening session channel with endpoint '{this.RemoteEndpoint.EndpointUrl}'.");
            this.logger?.LogInformation($"SecurityPolicy: '{this.RemoteEndpoint.SecurityPolicyUri}'.");
            this.logger?.LogInformation($"SecurityMode: '{this.RemoteEndpoint.SecurityMode}'.");
            this.logger?.LogInformation($"UserIdentity: '{this.UserIdentity}'.");

            await base.OnOpenAsync(token).ConfigureAwait(false);

            token.ThrowIfCancellationRequested();

            // if SessionId is provided then we skip the CreateSessionRequest and go directly to (re)ActivateSession.
            // requires from previous Session: SessionId, AuthenticationToken, RemoteNonce
            if (this.SessionId == null)
            {
                var localNonce           = this.RemoteEndpoint.SecurityMode != MessageSecurityMode.None ? this.GetNextNonce(NonceLength) : null;
                var localCertificate     = this.RemoteEndpoint.SecurityMode != MessageSecurityMode.None ? this.LocalCertificate : null;
                var createSessionRequest = new CreateSessionRequest
                {
                    ClientDescription       = this.LocalDescription,
                    EndpointUrl             = this.RemoteEndpoint.EndpointUrl,
                    SessionName             = this.LocalDescription.ApplicationName,
                    ClientNonce             = localNonce,
                    ClientCertificate       = localCertificate,
                    RequestedSessionTimeout = this.options.SessionTimeout,
                    MaxResponseMessageSize  = this.RemoteMaxMessageSize
                };

                var createSessionResponse = await this.CreateSessionAsync(createSessionRequest).ConfigureAwait(false);

                this.SessionId           = createSessionResponse.SessionId;
                this.AuthenticationToken = createSessionResponse.AuthenticationToken;
                this.RemoteNonce         = createSessionResponse.ServerNonce;

                // verify the server's certificate is the same as the certificate from the selected endpoint.
                if (this.RemoteEndpoint.ServerCertificate != null && !this.RemoteEndpoint.ServerCertificate.SequenceEqual(createSessionResponse.ServerCertificate))
                {
                    throw new ServiceResultException(StatusCodes.BadCertificateInvalid, "Server did not return the same certificate used to create the channel.");
                }

                // verify the server's signature.
                ISigner verifier = null;
                bool    verified = false;

                switch (this.RemoteEndpoint.SecurityPolicyUri)
                {
                case SecurityPolicyUris.Basic128Rsa15:
                case SecurityPolicyUris.Basic256:
                    verifier = SignerUtilities.GetSigner("SHA-1withRSA");
                    verifier.Init(false, this.RemotePublicKey);
                    verifier.BlockUpdate(localCertificate, 0, localCertificate.Length);
                    verifier.BlockUpdate(localNonce, 0, localNonce.Length);
                    verified = verifier.VerifySignature(createSessionResponse.ServerSignature.Signature);
                    break;

                case SecurityPolicyUris.Basic256Sha256:
                    verifier = SignerUtilities.GetSigner("SHA-256withRSA");
                    verifier.Init(false, this.RemotePublicKey);
                    verifier.BlockUpdate(localCertificate, 0, localCertificate.Length);
                    verifier.BlockUpdate(localNonce, 0, localNonce.Length);
                    verified = verifier.VerifySignature(createSessionResponse.ServerSignature.Signature);
                    break;

                default:
                    verified = true;
                    break;
                }

                verifier = null;
                if (!verified)
                {
                    throw new ServiceResultException(StatusCodes.BadApplicationSignatureInvalid, "Server did not provide a correct signature for the nonce data provided by the client.");
                }
            }

            // create client signature
            SignatureData clientSignature = null;
            ISigner       signer          = null;

            switch (this.RemoteEndpoint.SecurityPolicyUri)
            {
            case SecurityPolicyUris.Basic128Rsa15:
            case SecurityPolicyUris.Basic256:
                signer = SignerUtilities.GetSigner("SHA-1withRSA");
                signer.Init(true, this.LocalPrivateKey);
                signer.BlockUpdate(this.RemoteEndpoint.ServerCertificate, 0, this.RemoteEndpoint.ServerCertificate.Length);
                signer.BlockUpdate(this.RemoteNonce, 0, this.RemoteNonce.Length);
                clientSignature = new SignatureData
                {
                    Signature = signer.GenerateSignature(),
                    Algorithm = RsaSha1Signature,
                };

                break;

            case SecurityPolicyUris.Basic256Sha256:
                signer = SignerUtilities.GetSigner("SHA-256withRSA");
                signer.Init(true, this.LocalPrivateKey);
                signer.BlockUpdate(this.RemoteEndpoint.ServerCertificate, 0, this.RemoteEndpoint.ServerCertificate.Length);
                signer.BlockUpdate(this.RemoteNonce, 0, this.RemoteNonce.Length);
                clientSignature = new SignatureData
                {
                    Signature = signer.GenerateSignature(),
                    Algorithm = RsaSha256Signature,
                };

                break;

            default:
                clientSignature = new SignatureData();
                break;
            }

            signer = null;

            // supported UserIdentityToken types are AnonymousIdentityToken, UserNameIdentityToken, IssuedIdentityToken, X509IdentityToken
            UserIdentityToken identityToken  = null;
            SignatureData     tokenSignature = null;

            // if UserIdentity type is IssuedIdentity
            if (this.UserIdentity is IssuedIdentity)
            {
                var tokenPolicy = this.RemoteEndpoint.UserIdentityTokens.FirstOrDefault(t => t.TokenType == UserTokenType.IssuedToken);
                if (tokenPolicy == null)
                {
                    throw new ServiceResultException(StatusCodes.BadIdentityTokenRejected);
                }

                var             issuedIdentity = (IssuedIdentity)this.UserIdentity;
                byte[]          plainText      = Concat(issuedIdentity.TokenData, this.RemoteNonce);
                IBufferedCipher encryptor;
                byte[]          cipherText;
                int             pos;

                var secPolicyUri = tokenPolicy.SecurityPolicyUri ?? this.RemoteEndpoint.SecurityPolicyUri;
                switch (secPolicyUri)
                {
                case SecurityPolicyUris.Basic128Rsa15:
                    encryptor = CipherUtilities.GetCipher("RSA//PKCS1Padding");
                    encryptor.Init(true, this.RemotePublicKey);
                    cipherText    = new byte[encryptor.GetOutputSize(4 + plainText.Length)];
                    pos           = encryptor.ProcessBytes(BitConverter.GetBytes(plainText.Length), cipherText, 0);
                    pos           = encryptor.DoFinal(plainText, cipherText, pos);
                    identityToken = new IssuedIdentityToken
                    {
                        TokenData           = cipherText,
                        EncryptionAlgorithm = RsaV15KeyWrap,
                        PolicyId            = tokenPolicy.PolicyId
                    };

                    break;

                case SecurityPolicyUris.Basic256:
                case SecurityPolicyUris.Basic256Sha256:
                    encryptor = CipherUtilities.GetCipher("RSA//PKCS1Padding");
                    encryptor.Init(true, this.RemotePublicKey);
                    cipherText    = new byte[encryptor.GetOutputSize(4 + plainText.Length)];
                    pos           = encryptor.ProcessBytes(BitConverter.GetBytes(plainText.Length), cipherText, 0);
                    pos           = encryptor.DoFinal(plainText, cipherText, pos);
                    identityToken = new IssuedIdentityToken
                    {
                        TokenData           = cipherText,
                        EncryptionAlgorithm = RsaOaepKeyWrap,
                        PolicyId            = tokenPolicy.PolicyId
                    };

                    break;

                default:
                    identityToken = new IssuedIdentityToken
                    {
                        TokenData           = issuedIdentity.TokenData,
                        EncryptionAlgorithm = null,
                        PolicyId            = tokenPolicy.PolicyId
                    };
                    break;
                }

                tokenSignature = new SignatureData();
                plainText      = null;
                encryptor      = null;
                cipherText     = null;
            }

            // if UserIdentity type is X509Identity
            else if (this.UserIdentity is X509Identity)
            {
                throw new NotImplementedException("A user identity of X509Identity is not implemented.");

                /*
                 * var tokenPolicy = this.RemoteEndpoint.UserIdentityTokens.FirstOrDefault(t => t.TokenType == UserTokenType.Certificate);
                 * if (tokenPolicy == null)
                 * {
                 *  throw new ServiceResultException(StatusCodes.BadIdentityTokenRejected);
                 * }
                 *
                 * var x509Identity = (X509Identity)this.UserIdentity;
                 * identityToken = new X509IdentityToken { CertificateData = x509Identity.Certificate?.RawData, PolicyId = tokenPolicy.PolicyId };
                 * var secPolicyUri = tokenPolicy.SecurityPolicyUri ?? this.RemoteEndpoint.SecurityPolicyUri;
                 * switch (secPolicyUri)
                 * {
                 *  case SecurityPolicyUris.Basic128Rsa15:
                 *  case SecurityPolicyUris.Basic256:
                 *      var asymSigningKey = x509Identity.Certificate?.GetRSAPrivateKey();
                 *      if (asymSigningKey != null)
                 *      {
                 *          dataToSign = Concat(this.RemoteEndpoint.ServerCertificate, this.RemoteNonce);
                 *          tokenSignature = new SignatureData
                 *          {
                 *              Signature = asymSigningKey.SignData(dataToSign, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1),
                 *              Algorithm = RsaSha1Signature,
                 *          };
                 *          break;
                 *      }
                 *
                 *      tokenSignature = new SignatureData();
                 *      break;
                 *
                 *  case SecurityPolicyUris.Basic256Sha256:
                 *      var asymSigningKey256 = x509Identity.Certificate?.GetRSAPrivateKey();
                 *      if (asymSigningKey256 != null)
                 *      {
                 *          dataToSign = Concat(this.RemoteEndpoint.ServerCertificate, this.RemoteNonce);
                 *          tokenSignature = new SignatureData
                 *          {
                 *              Signature = asymSigningKey256.SignData(dataToSign, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1),
                 *              Algorithm = RsaSha256Signature,
                 *          };
                 *          break;
                 *      }
                 *
                 *      tokenSignature = new SignatureData();
                 *      break;
                 *
                 *  default:
                 *      tokenSignature = new SignatureData();
                 *      break;
                 * }
                 *
                 * dataToSign = null;
                 */
            }

            // if UserIdentity type is UserNameIdentity
            else if (this.UserIdentity is UserNameIdentity)
            {
                var tokenPolicy = this.RemoteEndpoint.UserIdentityTokens.FirstOrDefault(t => t.TokenType == UserTokenType.UserName);
                if (tokenPolicy == null)
                {
                    throw new ServiceResultException(StatusCodes.BadIdentityTokenRejected);
                }

                var             userNameIdentity = (UserNameIdentity)this.UserIdentity;
                byte[]          passwordBytes    = System.Text.Encoding.UTF8.GetBytes(userNameIdentity.Password);
                int             plainTextLength  = passwordBytes.Length + this.RemoteNonce.Length;
                IBufferedCipher encryptor;
                byte[]          cipherText;
                int             pos;

                var secPolicyUri = tokenPolicy.SecurityPolicyUri ?? this.RemoteEndpoint.SecurityPolicyUri;
                switch (secPolicyUri)
                {
                case SecurityPolicyUris.Basic128Rsa15:
                    encryptor = CipherUtilities.GetCipher("RSA//PKCS1Padding");
                    encryptor.Init(true, this.RemotePublicKey);
                    cipherText    = new byte[encryptor.GetOutputSize(4 + plainTextLength)];
                    pos           = encryptor.ProcessBytes(BitConverter.GetBytes(plainTextLength), cipherText, 0);
                    pos           = encryptor.ProcessBytes(passwordBytes, cipherText, pos);
                    pos           = encryptor.DoFinal(this.RemoteNonce, cipherText, pos);
                    identityToken = new UserNameIdentityToken
                    {
                        UserName            = userNameIdentity.UserName,
                        Password            = cipherText,
                        EncryptionAlgorithm = RsaV15KeyWrap,
                        PolicyId            = tokenPolicy.PolicyId
                    };

                    break;

                case SecurityPolicyUris.Basic256:
                case SecurityPolicyUris.Basic256Sha256:
                    encryptor = CipherUtilities.GetCipher("RSA//OAEPPADDING");
                    encryptor.Init(true, this.RemotePublicKey);
                    cipherText    = new byte[encryptor.GetOutputSize(4 + plainTextLength)];
                    pos           = encryptor.ProcessBytes(BitConverter.GetBytes(plainTextLength), cipherText, 0);
                    pos           = encryptor.ProcessBytes(passwordBytes, cipherText, pos);
                    pos           = encryptor.DoFinal(this.RemoteNonce, cipherText, pos);
                    identityToken = new UserNameIdentityToken
                    {
                        UserName            = userNameIdentity.UserName,
                        Password            = cipherText,
                        EncryptionAlgorithm = RsaOaepKeyWrap,
                        PolicyId            = tokenPolicy.PolicyId
                    };

                    break;

                default:
                    identityToken = new UserNameIdentityToken
                    {
                        UserName            = userNameIdentity.UserName,
                        Password            = passwordBytes,
                        EncryptionAlgorithm = null,
                        PolicyId            = tokenPolicy.PolicyId
                    };
                    break;
                }

                tokenSignature = new SignatureData();
                passwordBytes  = null;
                encryptor      = null;
                cipherText     = null;
            }

            // if UserIdentity type is AnonymousIdentity or null
            else
            {
                var tokenPolicy = this.RemoteEndpoint.UserIdentityTokens.FirstOrDefault(t => t.TokenType == UserTokenType.Anonymous);
                if (tokenPolicy == null)
                {
                    throw new ServiceResultException(StatusCodes.BadIdentityTokenRejected);
                }

                identityToken = new AnonymousIdentityToken {
                    PolicyId = tokenPolicy.PolicyId
                };
                tokenSignature = new SignatureData();
            }

            var activateSessionRequest = new ActivateSessionRequest
            {
                ClientSignature    = clientSignature,
                LocaleIds          = new[] { CultureInfo.CurrentUICulture.TwoLetterISOLanguageName },
                UserIdentityToken  = identityToken,
                UserTokenSignature = tokenSignature
            };
            var activateSessionResponse = await this.ActivateSessionAsync(activateSessionRequest).ConfigureAwait(false);

            this.RemoteNonce = activateSessionResponse.ServerNonce;

            // fetch namespace array, etc.
            var readValueIds = new ReadValueId[]
            {
                new ReadValueId
                {
                    NodeId      = NodeId.Parse(VariableIds.Server_NamespaceArray),
                    AttributeId = AttributeIds.Value
                },
                new ReadValueId
                {
                    NodeId      = NodeId.Parse(VariableIds.Server_ServerArray),
                    AttributeId = AttributeIds.Value
                }
            };
            var readRequest = new ReadRequest
            {
                NodesToRead = readValueIds
            };

            var readResponse = await this.ReadAsync(readRequest).ConfigureAwait(false);

            if (readResponse.Results.Length == 2)
            {
                if (StatusCode.IsGood(readResponse.Results[0].StatusCode))
                {
                    this.NamespaceUris.Clear();
                    this.NamespaceUris.AddRange(readResponse.Results[0].GetValueOrDefault <string[]>());
                }

                if (StatusCode.IsGood(readResponse.Results[1].StatusCode))
                {
                    this.ServerUris.Clear();
                    this.ServerUris.AddRange(readResponse.Results[1].GetValueOrDefault <string[]>());
                }
            }

            // create the keep alive subscription.
            var subscriptionRequest = new CreateSubscriptionRequest
            {
                RequestedPublishingInterval = DefaultPublishingInterval,
                RequestedMaxKeepAliveCount  = DefaultKeepaliveCount,
                RequestedLifetimeCount      = DefaultKeepaliveCount * 3,
                PublishingEnabled           = true,
            };
            var subscriptionResponse = await this.CreateSubscriptionAsync(subscriptionRequest).ConfigureAwait(true);

            // link up the dataflow blocks
            var id        = subscriptionResponse.SubscriptionId;
            var linkToken = this.LinkTo(this.actionBlock, pr => pr.SubscriptionId == id);

            // start publishing.
            this.stateMachineTask = Task.Run(() => this.StateMachineAsync(this.stateMachineCts.Token));
        }
Exemple #4
0
            public override void PerformTest()
            {
                int iCount = 100;

                byte[] salt = DigestUtilities.DoFinal(digest);

                PbeParametersGenerator pGen = new Pkcs12ParametersGenerator(digest);

                pGen.Init(
                    PbeParametersGenerator.Pkcs12PasswordToBytes(password),
                    salt,
                    iCount);

                ParametersWithIV parameters = (ParametersWithIV)
                                              pGen.GenerateDerivedParameters(baseAlgorithm, keySize, ivSize);

                KeyParameter encKey = (KeyParameter)parameters.Parameters;

                IBufferedCipher c;

                if (baseAlgorithm.Equals("RC4"))
                {
                    c = CipherUtilities.GetCipher(baseAlgorithm);

                    c.Init(true, encKey);
                }
                else
                {
                    c = CipherUtilities.GetCipher(baseAlgorithm + "/CBC/PKCS7Padding");

                    c.Init(true, parameters);
                }

                byte[] enc = c.DoFinal(salt);

                c = CipherUtilities.GetCipher(algorithm);

//					PBEKeySpec keySpec = new PBEKeySpec(password, salt, iCount);
//					SecretKeyFactory fact = SecretKeyFactory.getInstance(algorithm);
//
//					c.Init(false, fact.generateSecret(keySpec));

                Asn1Encodable algParams = PbeUtilities.GenerateAlgorithmParameters(
                    algorithm, salt, iCount);
                ICipherParameters cipherParams = PbeUtilities.GenerateCipherParameters(
                    algorithm, password, algParams);

                c.Init(false, cipherParams);

                byte[] dec = c.DoFinal(enc);

                if (!AreEqual(salt, dec))
                {
                    Fail("" + algorithm + "failed encryption/decryption test");
                }

                // NB: We don't support retrieving parameters from cipher
//				//
//				// get the parameters
//				//
//				AlgorithmParameters param = c.getParameters();
//				PBEParameterSpec spec = (PBEParameterSpec)param.getParameterSpec(PBEParameterSpec.class);
//
//				if (!AreEqual(salt, spec.getSalt()))
//				{
//					Fail("" + algorithm + "failed salt test");
//				}
//
//				if (iCount != spec.getIterationCount())
//				{
//					Fail("" + algorithm + "failed count test");
//				}

                // NB: This section just repeats earlier test passing 'param' separately
//				//
//				// try using parameters
//				//
//				keySpec = new PBEKeySpec(password);
//
//				c.Init(false, fact.generateSecret(keySpec), param);
//
//				dec = c.DoFinal(enc);
//
//				if (!AreEqual(salt, dec))
//				{
//					Fail("" + algorithm + "failed encryption/decryption test");
//				}
            }
Exemple #5
0
        private void doTestGP(
            int size,
            int privateValueSize,
            BigInteger g,
            BigInteger p)
        {
            IAsymmetricCipherKeyPairGenerator keyGen = GeneratorUtilities.GetKeyPairGenerator("ElGamal");

//			DHParameterSpec elParams = new DHParameterSpec(p, g);
//			keyGen.initialize(elParams);
            ElGamalParameters elParams           = new ElGamalParameters(p, g, privateValueSize);
            ElGamalKeyGenerationParameters elKgp = new ElGamalKeyGenerationParameters(
                new SecureRandom(), elParams);

            keyGen.Init(elKgp);

            AsymmetricCipherKeyPair keyPair = keyGen.GenerateKeyPair();
            SecureRandom            rand    = new SecureRandom();

            checkKeySize(privateValueSize, keyPair);

            IBufferedCipher cipher = CipherUtilities.GetCipher("ElGamal");

            cipher.Init(true, new ParametersWithRandom(keyPair.Public, rand));

            byte[] inBytes = Encoding.ASCII.GetBytes("This is a test");

            if (cipher.GetOutputSize(inBytes.Length) != (size / 8) * 2)
            {
                Fail("getOutputSize wrong on encryption");
            }

            byte[] outBytes = cipher.DoFinal(inBytes);

            cipher.Init(false, keyPair.Private);

            if (cipher.GetOutputSize(outBytes.Length) != (size / 8) - 1)
            {
                Fail("GetOutputSize wrong on decryption");
            }


            //
            // No Padding - maximum length
            //
            byte[] modBytes = ((ElGamalPublicKeyParameters)keyPair.Public).Parameters.P.ToByteArray();
            byte[] maxInput = new byte[modBytes.Length - 1];

            maxInput[0] |= 0x7f;

            cipher.Init(true, new ParametersWithRandom(keyPair.Public, rand));

            outBytes = cipher.DoFinal(maxInput);

            cipher.Init(false, keyPair.Private);

            outBytes = cipher.DoFinal(outBytes);

            if (!AreEqual(outBytes, maxInput))
            {
                Fail("NoPadding test failed on decrypt expected "
                     + Hex.ToHexString(maxInput) + " got "
                     + Hex.ToHexString(outBytes));
            }


            //
            // encrypt/decrypt
            //
            IBufferedCipher c1 = CipherUtilities.GetCipher("ElGamal");
            IBufferedCipher c2 = CipherUtilities.GetCipher("ElGamal");

            c1.Init(true, new ParametersWithRandom(keyPair.Public, rand));

            byte[] out1 = c1.DoFinal(inBytes);

            c2.Init(false, keyPair.Private);

            byte[] out2 = c2.DoFinal(out1);

            if (!AreEqual(inBytes, out2))
            {
                Fail(size + " encrypt test failed");
            }


            //
            // encrypt/decrypt with update
            //
            int outLen = c1.ProcessBytes(inBytes, 0, 2, out1, 0);

            outLen += c1.DoFinal(inBytes, 2, inBytes.Length - 2, out1, outLen);

            outLen = c2.ProcessBytes(out1, 0, 2, out2, 0);

            outLen += c2.DoFinal(out1, 2, out1.Length - 2, out2, outLen);

            if (!AreEqual(inBytes, out2))
            {
                Fail(size + " encrypt with update test failed");
            }



            //
            // public key encoding test
            //
//			byte[] pubEnc = keyPair.Public.GetEncoded();
            byte[] pubEnc = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(keyPair.Public).GetDerEncoded();

//			KeyFactory keyFac = KeyFactory.GetInstance("ElGamal");
//			X509EncodedKeySpec pubX509 = new X509EncodedKeySpec(pubEnc);
//			DHPublicKeyParameters pubKey = (DHPublicKeyParameters)keyFac.generatePublic(pubX509);
            ElGamalPublicKeyParameters pubKey = (ElGamalPublicKeyParameters)
                                                PublicKeyFactory.CreateKey(pubEnc);
            ElGamalParameters spec = pubKey.Parameters;

            if (!spec.G.Equals(elParams.G) || !spec.P.Equals(elParams.P))
            {
                Fail(size + " bit public key encoding/decoding test failed on parameters");
            }

            if (!((ElGamalPublicKeyParameters)keyPair.Public).Y.Equals(pubKey.Y))
            {
                Fail(size + " bit public key encoding/decoding test failed on y value");
            }

/*
 *                      //
 *                      // public key serialisation test
 *                      //
 *                      // TODO Is there some standard this serialization must conform to?
 *                      BinaryFormatter formatter = new BinaryFormatter();
 *
 *                      MemoryStream bOut = new MemoryStream();
 * //			ObjectOutputStream oOut = new ObjectOutputStream(bOut);
 * //			oOut.writeObject(keyPair.Public);
 *                      formatter.Serialize(bOut, keyPair.Public);
 *
 *                      MemoryStream bIn = new MemoryStream(bOut.ToArray(), false);
 * //			ObjectInputStream oIn = new ObjectInputStream(bIn);
 * //			pubKey = (DHPublicKeyParameters)oIn.readObject();
 *                      pubKey = (ElGamalPublicKeyParameters) formatter.Deserialize(bIn);
 *                      spec = pubKey.Parameters;
 *
 *                      if (!spec.G.Equals(elParams.G) || !spec.P.Equals(elParams.P))
 *                      {
 *                              Fail(size + " bit public key serialisation test failed on parameters");
 *                      }
 *
 *                      if (!((ElGamalPublicKeyParameters )keyPair.Public).Y.Equals(pubKey.Y))
 *                      {
 *                              Fail(size + " bit public key serialisation test failed on y value");
 *                      }
 */

            //
            // private key encoding test
            //
            // TODO Keys don't support GetEncoded
//			byte[] privEnc = keyPair.Private.GetEncoded();
            byte[] privEnc = PrivateKeyInfoFactory.CreatePrivateKeyInfo(keyPair.Private).GetDerEncoded();

//			PKCS8EncodedKeySpec privPKCS8 = new PKCS8EncodedKeySpec(privEnc);
//			DHPrivateKeyParameters privKey = (DHPrivateKeyParameters)keyFac.generatePrivate(privPKCS8);
            ElGamalPrivateKeyParameters privKey = (ElGamalPrivateKeyParameters)
                                                  PrivateKeyFactory.CreateKey(privEnc);

            spec = privKey.Parameters;

            if (!spec.G.Equals(elParams.G) || !spec.P.Equals(elParams.P))
            {
                Fail(size + " bit private key encoding/decoding test failed on parameters");
            }

            if (!((ElGamalPrivateKeyParameters)keyPair.Private).X.Equals(privKey.X))
            {
                Fail(size + " bit private key encoding/decoding test failed on y value");
            }

/*
 *                      //
 *                      // private key serialisation test
 *                      //
 *                      bOut = new MemoryStream();
 * //			oOut = new ObjectOutputStream(bOut);
 * //			oOut.writeObject(keyPair.Private);
 *                      formatter.Serialize(bOut, keyPair.Private);
 *
 *                      bIn = new MemoryStream(bOut.ToArray(), false);
 * //			oIn = new ObjectInputStream(bIn);
 * //			privKey = (DHPrivateKeyParameters)oIn.readObject();
 *                      privKey = (ElGamalPrivateKeyParameters) formatter.Deserialize(bIn);
 *                      spec = privKey.Parameters;
 *
 *                      if (!spec.G.Equals(elParams.G) || !spec.P.Equals(elParams.P))
 *                      {
 *                              Fail(size + " bit private key serialisation test failed on parameters");
 *                      }
 *
 *                      if (!((ElGamalPrivateKeyParameters) keyPair.Private).X.Equals(privKey.X))
 *                      {
 *                              Fail(size + " bit private key serialisation test failed on y value");
 *                      }
 */
        }
Exemple #6
0
            private byte[] EncryptSessionInfo(byte[] sessionInfo, SecureRandom random)
            {
                if (pubKey.Algorithm != PublicKeyAlgorithmTag.ECDH)
                {
                    IBufferedCipher c;
                    switch (pubKey.Algorithm)
                    {
                    case PublicKeyAlgorithmTag.RsaEncrypt:
                    case PublicKeyAlgorithmTag.RsaGeneral:
                        c = CipherUtilities.GetCipher("RSA//PKCS1Padding");
                        break;

                    case PublicKeyAlgorithmTag.ElGamalEncrypt:
                    case PublicKeyAlgorithmTag.ElGamalGeneral:
                        c = CipherUtilities.GetCipher("ElGamal/ECB/PKCS1Padding");
                        break;

                    case PublicKeyAlgorithmTag.Dsa:
                        throw new PgpException("Can't use DSA for encryption.");

                    case PublicKeyAlgorithmTag.ECDsa:
                        throw new PgpException("Can't use ECDSA for encryption.");

                    default:
                        throw new PgpException("unknown asymmetric algorithm: " + pubKey.Algorithm);
                    }

                    AsymmetricKeyParameter akp = pubKey.GetKey();
                    c.Init(true, new ParametersWithRandom(akp, random));
                    return(c.DoFinal(sessionInfo));
                }

                ECDHPublicBcpgKey ecKey = (ECDHPublicBcpgKey)pubKey.PublicKeyPacket.Key;

                // Generate the ephemeral key pair
                IAsymmetricCipherKeyPairGenerator gen = GeneratorUtilities.GetKeyPairGenerator("ECDH");

                gen.Init(new ECKeyGenerationParameters(ecKey.CurveOid, random));

                AsymmetricCipherKeyPair ephKp   = gen.GenerateKeyPair();
                ECPrivateKeyParameters  ephPriv = (ECPrivateKeyParameters)ephKp.Private;
                ECPublicKeyParameters   ephPub  = (ECPublicKeyParameters)ephKp.Public;

                ECPublicKeyParameters pub = (ECPublicKeyParameters)pubKey.GetKey();
                ECPoint S = pub.Q.Multiply(ephPriv.D).Normalize();

                KeyParameter key = new KeyParameter(Rfc6637Utilities.CreateKey(pubKey.PublicKeyPacket, S));

                IWrapper w = PgpUtilities.CreateWrapper(ecKey.SymmetricKeyAlgorithm);

                w.Init(true, new ParametersWithRandom(key, random));

                byte[] paddedSessionData = PgpPad.PadSessionData(sessionInfo);

                byte[] C  = w.Wrap(paddedSessionData, 0, paddedSessionData.Length);
                byte[] VB = new MPInteger(new BigInteger(1, ephPub.Q.GetEncoded(false))).GetEncoded();

                byte[] rv = new byte[VB.Length + 1 + C.Length];

                Array.Copy(VB, 0, rv, 0, VB.Length);
                rv[VB.Length] = (byte)C.Length;
                Array.Copy(C, 0, rv, VB.Length + 1, C.Length);

                return(rv);
            }
Exemple #7
0
        /// <summary>Return the decrypted data stream for the packet.</summary>
        public Stream GetDataStream(
            PgpPrivateKey privKey)
        {
            byte[] plain = fetchSymmetricKeyData(privKey);

            IBufferedCipher c2;
            string          cipherName = PgpUtilities.GetSymmetricCipherName((SymmetricKeyAlgorithmTag)plain[0]);
            string          cName      = cipherName;

            try
            {
                if (encData is SymmetricEncIntegrityPacket)
                {
                    cName += "/CFB/NoPadding";
                }
                else
                {
                    cName += "/OpenPGPCFB/NoPadding";
                }

                c2 = CipherUtilities.GetCipher(cName);
            }
            catch (PgpException e)
            {
                throw e;
            }
            catch (Exception e)
            {
                throw new PgpException("exception creating cipher", e);
            }

            if (c2 == null)
            {
                return(encData.GetInputStream());
            }

            try
            {
                KeyParameter key = ParameterUtilities.CreateKeyParameter(
                    cipherName, plain, 1, plain.Length - 3);

                byte[] iv = new byte[c2.GetBlockSize()];

                c2.Init(false, new ParametersWithIV(key, iv));

                encStream = BcpgInputStream.Wrap(new CipherStream(encData.GetInputStream(), c2, null));

                if (encData is SymmetricEncIntegrityPacket)
                {
                    truncStream = new TruncatedStream(encStream);

                    string  digestName = PgpUtilities.GetDigestName(HashAlgorithmTag.Sha1);
                    IDigest digest     = DigestUtilities.GetDigest(digestName);

                    encStream = new DigestStream(truncStream, digest, null);
                }

                if (Streams.ReadFully(encStream, iv, 0, iv.Length) < iv.Length)
                {
                    throw new EndOfStreamException("unexpected end of stream.");
                }

                int v1 = encStream.ReadByte();
                int v2 = encStream.ReadByte();

                if (v1 < 0 || v2 < 0)
                {
                    throw new EndOfStreamException("unexpected end of stream.");
                }

                // Note: the oracle attack on the "quick check" bytes is deemed
                // a security risk for typical public key encryption usages,
                // therefore we do not perform the check.

//				bool repeatCheckPassed =
//					iv[iv.Length - 2] == (byte)v1
//					&&	iv[iv.Length - 1] == (byte)v2;
//
//				// Note: some versions of PGP appear to produce 0 for the extra
//				// bytes rather than repeating the two previous bytes
//				bool zeroesCheckPassed =
//					v1 == 0
//					&&	v2 == 0;
//
//				if (!repeatCheckPassed && !zeroesCheckPassed)
//				{
//					throw new PgpDataValidationException("quick check failed.");
//				}

                return(encStream);
            }
            catch (PgpException e)
            {
                throw e;
            }
            catch (Exception e)
            {
                throw new PgpException("Exception starting decryption", e);
            }
        }
Exemple #8
0
    private CmsEnvelopedData Generate(CmsProcessable content, string encryptionOid, CipherKeyGenerator keyGen)
    {
        AlgorithmIdentifier algorithmIdentifier = null;
        KeyParameter        keyParameter;
        Asn1OctetString     encryptedContent;

        try
        {
            byte[] array = keyGen.GenerateKey();
            keyParameter = ParameterUtilities.CreateKeyParameter(encryptionOid, array);
            Asn1Encodable asn1Params = GenerateAsn1Parameters(encryptionOid, array);
            algorithmIdentifier = GetAlgorithmIdentifier(encryptionOid, keyParameter, asn1Params, out ICipherParameters cipherParameters);
            IBufferedCipher cipher = CipherUtilities.GetCipher(encryptionOid);
            cipher.Init(forEncryption: true, new ParametersWithRandom(cipherParameters, rand));
            MemoryStream memoryStream = new MemoryStream();
            CipherStream cipherStream = new CipherStream(memoryStream, null, cipher);
            content.Write(cipherStream);
            Platform.Dispose(cipherStream);
            encryptedContent = new BerOctetString(memoryStream.ToArray());
        }
        catch (SecurityUtilityException e)
        {
            throw new CmsException("couldn't create cipher.", e);
        }
        catch (InvalidKeyException e2)
        {
            throw new CmsException("key invalid in message.", e2);
        }
        catch (IOException e3)
        {
            throw new CmsException("exception decoding algorithm parameters.", e3);
        }
        Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector();

        foreach (RecipientInfoGenerator recipientInfoGenerator in recipientInfoGenerators)
        {
            try
            {
                asn1EncodableVector.Add(recipientInfoGenerator.Generate(keyParameter, rand));
            }
            catch (InvalidKeyException e4)
            {
                throw new CmsException("key inappropriate for algorithm.", e4);
            }
            catch (GeneralSecurityException e5)
            {
                throw new CmsException("error making encrypted content.", e5);
            }
        }
        EncryptedContentInfo encryptedContentInfo = new EncryptedContentInfo(CmsObjectIdentifiers.Data, algorithmIdentifier, encryptedContent);
        Asn1Set unprotectedAttrs = null;

        if (unprotectedAttributeGenerator != null)
        {
            Org.BouncyCastle.Asn1.Cms.AttributeTable attributes = unprotectedAttributeGenerator.GetAttributes(Platform.CreateHashtable());
            unprotectedAttrs = new BerSet(attributes.ToAsn1EncodableVector());
        }
        ContentInfo contentInfo = new ContentInfo(CmsObjectIdentifiers.EnvelopedData, new EnvelopedData(null, new DerSet(asn1EncodableVector), encryptedContentInfo, unprotectedAttrs));

        return(new CmsEnvelopedData(contentInfo));
    }
Exemple #9
0
        internal static byte[] AESKeyWrapDecrypt(byte[] rgbKey, byte[] rgbEncryptedWrappedKeyData)
        {
            int N = (rgbEncryptedWrappedKeyData.Length >> 3) - 1;

            // The information wrapped need not actually be a key, but it needs to be a multiple of 64 bits
            if ((rgbEncryptedWrappedKeyData.Length % 8 != 0) || N <= 0)
            {
                throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_KW_BadKeySize);
            }

            byte[]          rgbOutput = new byte[N << 3];
            IBufferedCipher dec       = null;

            try
            {
                // Use ECB mode, no padding
                dec = CipherUtilities.GetCipher("AES/ECB/NOPADDING");
                dec.Init(false, new KeyParameter(rgbKey));

                // special case: only 1 block -- 8 bytes
                if (N == 1)
                {
                    byte[] temp = dec.DoFinal(rgbEncryptedWrappedKeyData);
                    // checksum the key
                    for (int index = 0; index < 8; index++)
                    {
                        if (temp[index] != s_rgbAES_KW_IV[index])
                        {
                            throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_BadWrappedKeySize);
                        }
                    }
                    // rgbOutput is LSB(temp)
                    Buffer.BlockCopy(temp, 8, rgbOutput, 0, 8);
                    return(rgbOutput);
                }
                // second case: more than 1 block
                long t = 0;
                // initialize the C_i's
                Buffer.BlockCopy(rgbEncryptedWrappedKeyData, 8, rgbOutput, 0, rgbOutput.Length);
                byte[] rgbA     = new byte[8];
                byte[] rgbBlock = new byte[16];
                Buffer.BlockCopy(rgbEncryptedWrappedKeyData, 0, rgbA, 0, 8);
                for (int j = 5; j >= 0; j--)
                {
                    for (int i = N; i >= 1; i--)
                    {
                        t = i + j * N;
                        for (int k = 0; k < 8; k++)
                        {
                            byte tmp = (byte)((t >> (8 * (7 - k))) & 0xFF);
                            rgbA[k] ^= tmp;
                        }
                        Buffer.BlockCopy(rgbA, 0, rgbBlock, 0, 8);
                        Buffer.BlockCopy(rgbOutput, 8 * (i - 1), rgbBlock, 8, 8);
                        byte[] rgbB = dec.DoFinal(rgbBlock);
                        Buffer.BlockCopy(rgbB, 8, rgbOutput, 8 * (i - 1), 8);
                        Buffer.BlockCopy(rgbB, 0, rgbA, 0, 8);
                    }
                }
                // checksum the key
                for (int index = 0; index < 8; index++)
                {
                    if (rgbA[index] != s_rgbAES_KW_IV[index])
                    {
                        throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_BadWrappedKeySize);
                    }
                }
                return(rgbOutput);
            }
            finally
            {
            }
        }
Exemple #10
0
        internal static byte[] Crypt(
            bool encrypt,
            byte[]  bytes,
            char[]  password,
            string dekAlgName,
            byte[]  iv)
        {
            PemBaseAlg baseAlg;
            PemMode    mode;

            ParseDekAlgName(dekAlgName, out baseAlg, out mode);

            string padding;

            switch (mode)
            {
            case PemMode.CBC:
            case PemMode.ECB:
                padding = "PKCS5Padding";
                break;

            case PemMode.CFB:
            case PemMode.OFB:
                padding = "NoPadding";
                break;

            default:
                throw new EncryptionException("Unknown DEK algorithm: " + dekAlgName);
            }

            string algorithm;

            byte[] salt = iv;
            switch (baseAlg)
            {
            case PemBaseAlg.AES_128:
            case PemBaseAlg.AES_192:
            case PemBaseAlg.AES_256:
                algorithm = "AES";
                if (salt.Length > 8)
                {
                    salt = new byte[8];
                    Array.Copy(iv, 0, salt, 0, salt.Length);
                }
                break;

            case PemBaseAlg.BF:
                algorithm = "BLOWFISH";
                break;

            case PemBaseAlg.DES:
                algorithm = "DES";
                break;

            case PemBaseAlg.DES_EDE:
            case PemBaseAlg.DES_EDE3:
                algorithm = "DESede";
                break;

            case PemBaseAlg.RC2:
            case PemBaseAlg.RC2_40:
            case PemBaseAlg.RC2_64:
                algorithm = "RC2";
                break;

            default:
                throw new EncryptionException("Unknown DEK algorithm: " + dekAlgName);
            }

            string          cipherName = algorithm + "/" + mode + "/" + padding;
            IBufferedCipher cipher     = CipherUtilities.GetCipher(cipherName);

            ICipherParameters cParams = GetCipherParameters(password, baseAlg, salt);

            if (mode != PemMode.ECB)
            {
                cParams = new ParametersWithIV(cParams, iv);
            }

            cipher.Init(encrypt, cParams);

            return(cipher.DoFinal(bytes));
        }
Exemple #11
0
        private static bool EncryptFile(ref string filename)
        {
            byte[] data = null;
            try
            {
                data = File.ReadAllBytes(filename);
            }
            catch (Exception)
            {
                Console.WriteLine("error loading file to encrypt");
                Environment.Exit(-1);
                return(false);
            }

            if (null == data)
            {
                Console.WriteLine("error loading file to encrypt (2)");
                Environment.Exit(-1);
                return(false);
            }


            SecureRandom random = new SecureRandom();

            byte[] secretKeyData = new byte[32];
            random.NextBytes(secretKeyData);

            byte[] IV = new byte[16];
            for (int i = 0; i < IV.Length; i++)
            {
                IV[i] = 0x00;
            }

            KeyParameter     secretKey     = new KeyParameter(secretKeyData);
            IBufferedCipher  cipher        = CipherUtilities.GetCipher("AES/GCM/NoPadding");
            ParametersWithIV aesIVKeyParam = new ParametersWithIV(secretKey, IV);

            cipher.Init(true, aesIVKeyParam);
            MemoryStream bOut = new MemoryStream();
            CipherStream cOut = new CipherStream(bOut, null, cipher);

            cOut.Write(data, 0, data.Length);
            cOut.Close();
            byte[] encryted = bOut.ToArray();


            X509CertificateParser certParser = new X509CertificateParser();

            Org.BouncyCastle.X509.X509Certificate cert = certParser.ReadCertificate(EncryptionCertificate);
            AsymmetricKeyParameter pubkey = cert.GetPublicKey();

            //Pkcs1Encoding encryptEngine = new Pkcs1Encoding(new RsaEngine()); // V2
            OaepEncoding encryptEngine = new OaepEncoding(new RsaEngine()); // V3

            encryptEngine.Init(true, pubkey);
            byte[] keyblock = encryptEngine.ProcessBlock(secretKeyData, 0, secretKeyData.Length);



            List <byte> ResultBlock = new List <byte>();

            ResultBlock.AddRange(encryted);
            ResultBlock.AddRange(keyblock);

            filename += ".enc";
            File.WriteAllBytes(filename, ResultBlock.ToArray());
            return(true);
        }
Exemple #12
0
        private void doTestEcb(
            int strength,
            byte[]  keyBytes,
            byte[]  input,
            byte[]  output)
        {
            IBufferedCipher inCipher, outCipher;
            CipherStream    cIn, cOut;
            MemoryStream    bIn, bOut;

            KeyParameter key = ParameterUtilities.CreateKeyParameter("GOST28147", keyBytes);

            inCipher  = CipherUtilities.GetCipher("GOST28147/ECB/NoPadding");
            outCipher = CipherUtilities.GetCipher("GOST28147/ECB/NoPadding");
            outCipher.Init(true, key);
            inCipher.Init(false, key);

            //
            // encryption pass
            //
            bOut = new MemoryStream();
            cOut = new CipherStream(bOut, null, outCipher);

            for (int i = 0; i != input.Length / 2; i++)
            {
                cOut.WriteByte(input[i]);
            }
            cOut.Write(input, input.Length / 2, input.Length - input.Length / 2);
            cOut.Close();

            byte[] bytes = bOut.ToArray();

            if (!AreEqual(bytes, output))
            {
                Fail("GOST28147 failed encryption - expected "
                     + Hex.ToHexString(output) + " got " + Hex.ToHexString(bytes));
            }

            //
            // decryption pass
            //
            bIn = new MemoryStream(bytes, false);
            cIn = new CipherStream(bIn, inCipher, null);

            BinaryReader dIn = new BinaryReader(cIn);

            bytes = new byte[input.Length];

            for (int i = 0; i != input.Length / 2; i++)
            {
                bytes[i] = dIn.ReadByte();
            }

            int remaining = bytes.Length - input.Length / 2;

            byte[] extra = dIn.ReadBytes(remaining);
            if (extra.Length < remaining)
            {
                throw new EndOfStreamException();
            }
            extra.CopyTo(bytes, input.Length / 2);

            if (!AreEqual(bytes, input))
            {
                Fail("GOST28147 failed decryption - expected " + Hex.ToHexString(input) + " got " + Hex.ToHexString(bytes));
            }
        }
Exemple #13
0
        public void WriteObject(
            object obj,
            string algorithm,
            char[]                  password,
            SecureRandom random)
        {
            if (obj == null)
            {
                throw new ArgumentNullException("obj");
            }
            if (algorithm == null)
            {
                throw new ArgumentNullException("algorithm");
            }
            if (password == null)
            {
                throw new ArgumentNullException("password");
            }
            if (random == null)
            {
                throw new ArgumentNullException("random");
            }


            byte[] keyData = null;

            if (obj is RsaPrivateCrtKeyParameters)
            {
                RsaPrivateCrtKeyParameters k = (RsaPrivateCrtKeyParameters)obj;

                keyData = PrivateKeyInfoFactory.CreatePrivateKeyInfo(k).PrivateKey.GetEncoded();
            }
            else
            {
                // TODO Support other types?
                throw new ArgumentException("Object type not supported: " + obj.GetType().FullName, "obj");
            }


            byte[] salt = new byte[8];
            random.NextBytes(salt);

            OpenSslPbeParametersGenerator pGen = new OpenSslPbeParametersGenerator();

            pGen.Init(PbeParametersGenerator.Pkcs5PasswordToBytes(password), salt);

            ICipherParameters secretKey = null;

            if (algorithm.ToUpper(CultureInfo.InvariantCulture).Equals("DESEDE"))
            {
                // generate key
                int keyLength = 24;
                secretKey = pGen.GenerateDerivedParameters(keyLength * 8);
            }
            else
            {
                throw new IOException("unknown algorithm in WriteObject");
            }


            byte[] encData = null;

            // cipher
            try
            {
                IBufferedCipher c = CipherUtilities.GetCipher("DESede/CBC/PKCS5Padding");
                c.Init(true, new ParametersWithIV(secretKey, salt));

                encData = c.DoFinal(keyData);
            }
            catch (Exception e)
            {
                throw new IOException("exception using cipher: " + e.ToString());
            }

            // write the data
            string type = "RSA PRIVATE KEY";

            WriteHeader(type);
            writer.WriteLine("Proc-Type: 4,ENCRYPTED");
            writer.Write("DEK-Info: DES-EDE3-CBC,");
            WriteHexEncoded(salt);
            writer.WriteLine();
            WriteBase64Encoded(encData);
            WriteFooter(type);
        }
        public static object CreateFromKnownName(string name)
        {
            switch (name)
            {
            case "http://www.w3.org/TR/2001/REC-xml-c14n-20010315":
                return(new XmlDsigC14NTransform());

            case "http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments":
                return(new XmlDsigC14NWithCommentsTransform());

            case "http://www.w3.org/2001/10/xml-exc-c14n#":
                return(new XmlDsigExcC14NTransform());

            case "http://www.w3.org/2001/10/xml-exc-c14n#WithComments":
                return(new XmlDsigExcC14NWithCommentsTransform());

            case "http://www.w3.org/2000/09/xmldsig#base64":
                return(new XmlDsigBase64Transform());

            case "http://www.w3.org/TR/1999/REC-xpath-19991116":
                return(new XmlDsigXPathTransform());

            case "http://www.w3.org/TR/1999/REC-xslt-19991116":
                return(new XmlDsigXsltTransform());

            case "http://www.w3.org/2000/09/xmldsig#enveloped-signature":
                return(new XmlDsigEnvelopedSignatureTransform());

            case "http://www.w3.org/2002/07/decrypt#XML":
                return(new XmlDecryptionTransform());

            case "urn:mpeg:mpeg21:2003:01-REL-R-NS:licenseTransform":
                return(new XmlLicenseTransform());

            case "http://www.w3.org/2000/09/xmldsig# X509Data":
                return(new KeyInfoX509Data());

            case "http://www.w3.org/2000/09/xmldsig# KeyName":
                return(new KeyInfoName());

            case "http://www.w3.org/2000/09/xmldsig# KeyValue/DSAKeyValue":
                return(new DSAKeyValue());

            case "http://www.w3.org/2000/09/xmldsig# KeyValue/RSAKeyValue":
                return(new RSAKeyValue());

            case "http://www.w3.org/2000/09/xmldsig# RetrievalMethod":
                return(new KeyInfoRetrievalMethod());

            case "http://www.w3.org/2001/04/xmlenc# EncryptedKey":
                return(new KeyInfoEncryptedKey());

            case "http://www.w3.org/2000/09/xmldsig#dsa-sha1":
            case "System.Security.Cryptography.DSASignatureDescription":
                //return SignerUtilities.GetSigner("DSAWITHSHA1");
                return(new DsaDigestSigner2(new DsaSigner(), new Sha1Digest()));

            case "http://www.w3.org/2000/09/xmldsig#rsa-sha1":
            case "System.Security.Cryptography.RSASignatureDescription":
                return(SignerUtilities.GetSigner("SHA1WITHRSA"));

            case "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256":
                return(SignerUtilities.GetSigner("SHA256WITHRSA"));

            case "http://www.w3.org/2001/04/xmldsig-more#rsa-sha384":
                return(SignerUtilities.GetSigner("SHA384WITHRSA"));

            case "http://www.w3.org/2001/04/xmldsig-more#rsa-sha512":
                return(SignerUtilities.GetSigner("SHA512WITHRSA"));

            case "urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102001-gostr3411":
            case "http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411":
                return(SignerUtilities.GetSigner("GOST3411WITHECGOST3410"));

            case "urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102012-gostr34112012256":
                return(new Gost3410DigestSigner(new ECGost3410Signer(), new Gost3411_2012_256Digest()));

            case "urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102012-gostr34112012512":
                return(new Gost3410DigestSigner(new ECGost3410Signer(), new Gost3411_2012_512Digest()));

            // workarounds for issue https://github.com/dotnet/corefx/issues/16563
            // remove attribute from this method when removing them
            case "http://www.w3.org/2000/09/xmldsig#sha1":
                return(DigestUtilities.GetDigest("SHA-1"));

            case "http://www.w3.org/2001/04/xmlenc#sha256":
                return(DigestUtilities.GetDigest("SHA-256"));

            case "http://www.w3.org/2001/04/xmldsig-more#sha384":
            case "SHA384":
                return(DigestUtilities.GetDigest("SHA-384"));

            case "http://www.w3.org/2001/04/xmlenc#sha512":
                return(DigestUtilities.GetDigest("SHA-512"));

            case "http://www.w3.org/2001/04/xmlenc#ripemd160":
                return(DigestUtilities.GetDigest("RIPEMD-160"));

            case "MD5":
                return(DigestUtilities.GetDigest("MD5"));

            case "urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr3411":
            case "http://www.w3.org/2001/04/xmldsig-more#gostr3411":
                return(DigestUtilities.GetDigest("GOST3411"));

            case "urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34112012-256":
                return(DigestUtilities.GetDigest("GOST3411-2012-256"));

            case "urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34112012-512":
                return(DigestUtilities.GetDigest("GOST3411-2012-512"));

            case "http://www.w3.org/2001/04/xmldsig-more#hmac-md5":
                return(MacUtilities.GetMac("HMAC-MD5"));

            case "http://www.w3.org/2001/04/xmldsig-more#hmac-sha256":
                return(MacUtilities.GetMac("HMAC-SHA256"));

            case "http://www.w3.org/2001/04/xmldsig-more#hmac-sha384":
                return(MacUtilities.GetMac("HMAC-SHA384"));

            case "http://www.w3.org/2001/04/xmldsig-more#hmac-sha512":
                return(MacUtilities.GetMac("HMAC-SHA512"));

            case "http://www.w3.org/2001/04/xmldsig-more#hmac-ripemd160":
                return(MacUtilities.GetMac("HMAC-RIPEMD160"));

            case "http://www.w3.org/2001/04/xmlenc#des-cbc":
                return(CipherUtilities.GetCipher("DES/CBC/PKCS7Padding"));

            case "http://www.w3.org/2001/04/xmlenc#tripledes-cbc":
                return(CipherUtilities.GetCipher("DESede/CBC/PKCS7Padding"));

            case "http://www.w3.org/2001/04/xmlenc#aes128-cbc":
            case "http://www.w3.org/2001/04/xmlenc#kw-aes128":
                return(new PaddedBufferedBlockCipher(new CbcBlockCipher(new RijndaelEngine(128)), new Pkcs7Padding()));

            case "http://www.w3.org/2001/04/xmlenc#aes192-cbc":
            case "http://www.w3.org/2001/04/xmlenc#kw-aes192":
                return(new PaddedBufferedBlockCipher(new CbcBlockCipher(new RijndaelEngine(192)), new Pkcs7Padding()));

            case "http://www.w3.org/2001/04/xmlenc#aes256-cbc":
            case "http://www.w3.org/2001/04/xmlenc#kw-aes256":
                return(new PaddedBufferedBlockCipher(new CbcBlockCipher(new RijndaelEngine(256)), new Pkcs7Padding()));
            }

            return(null);
        }
Exemple #15
0
        // TODO Make private again and call from PerformTest
        public void doTestExceptions()
        {
            // TODO Put back in
//			SecretKeyFactory skF = null;
//
//			try
//			{
//				skF = SecretKeyFactory.getInstance("DESede");
//			}
//			catch (Exception e)
//			{
//				Fail("unexpected exception.", e);
//			}
//
//			KeySpec ks = null;
//			SecretKey secKey = null;
//			byte[] bb = new byte[24];
//
//			try
//			{
//				skF.getKeySpec(null, null);
//
//				Fail("failed exception test - no exception thrown");
//			}
//			catch (InvalidKeySpecException e)
//			{
//				// ignore okay
//			}
//			catch (Exception e)
//			{
//				Fail("failed exception test.", e);
//			}
//			try
//			{
//				ks = (KeySpec)new DESedeKeySpec(bb);
//				skF.getKeySpec(null, ks.getClass());
//
//				Fail("failed exception test - no exception thrown");
//			}
//			catch (InvalidKeySpecException e)
//			{
//				// ignore okay;
//			}
//			catch (Exception e)
//			{
//				Fail("failed exception test.", e);
//			}
//			try
//			{
//				skF.getKeySpec(secKey, null);
//			}
//			catch (InvalidKeySpecException e)
//			{
//				// ignore okay
//			}
//			catch (Exception e)
//			{
//				Fail("failed exception test.", e);
//			}

            try
            {
                CipherKeyGenerator kg = GeneratorUtilities.GetKeyGenerator("DESede");

                try
                {
                    kg.Init(new KeyGenerationParameters(new SecureRandom(), int.MinValue));

                    Fail("failed exception test - no exception thrown");
                }
//				catch (InvalidParameterException)
                catch (ArgumentException)
                {
                    // ignore okay
                }
                catch (Exception e)
                {
                    Fail("failed exception test.", e);
                }
            }
            catch (Exception e)
            {
                Fail("unexpected exception.", e);
            }

            // TODO Put back in
//			try
//			{
//				skF = SecretKeyFactory.getInstance("DESede");
//
//				try
//				{
//					skF.translateKey(null);
//
//					Fail("failed exception test - no exception thrown");
//				}
//				catch (InvalidKeyException)
//				{
//					// ignore okay
//				}
//				catch (Exception e)
//				{
//					Fail("failed exception test.", e);
//				}
//			}
//			catch (Exception e)
//			{
//				Fail("unexpected exception.", e);
//			}

//			try
//			{
//				byte[] rawDESKey = { (byte)128, (byte)131, (byte)133, (byte)134,
//						(byte)137, (byte)138, (byte)140, (byte)143 };
//
////				SecretKeySpec cipherKey = new SecretKeySpec(rawDESKey, "DES");
//				KeyParameter cipherKey = new DesParameters(rawDESKey);
//
//				IBufferedCipher cipher = CipherUtilities.GetCipher("DES/CBC/NoPadding");
//
//				try
//				{
//					// According specification engineInit(int opmode, Key key,
//					// SecureRandom random) throws InvalidKeyException if this
//					// cipher is being
//					// initialized for decryption and requires algorithm parameters
//					// that cannot be determined from the given key
////					cipher.Init(false, cipherKey, (SecureRandom)null);
//					cipher.Init(false, new ParametersWithRandom(cipherKey, new SecureRandom()));
//
//					Fail("failed exception test - no InvalidKeyException thrown");
//				}
//				catch (InvalidKeyException)
//				{
//					// ignore
//				}
//			}
//			catch (Exception e)
//			{
//				Fail("unexpected exception.", e);
//			}

            try
            {
//				byte[] rawDESKey = { -128, -125, -123, -122, -119, -118 };
                byte[] rawDESKey = { 128, 131, 133, 134, 137, 138 };

//				SecretKeySpec cipherKey = new SecretKeySpec(rawDESKey, "DES");

//				IBufferedCipher cipher = CipherUtilities.GetCipher("DES/ECB/NoPadding");
                try
                {
                    KeyParameter cipherKey = new DesParameters(rawDESKey);

                    // According specification engineInit(int opmode, Key key,
                    // SecureRandom random) throws InvalidKeyException if the given
                    // key is inappropriate for initializing this cipher
//					cipher.Init(true, cipherKey);

//					Fail("failed exception test - no InvalidKeyException thrown");
                    Fail("failed exception test - no ArgumentException thrown");
                }
//				catch (InvalidKeyException)
                catch (ArgumentException)
                {
                    // ignore
                }
            }
            catch (Exception e)
            {
                Fail("unexpected exception.", e);
            }

//			try
//			{
////				byte[] rawDESKey = { -128, -125, -123, -122, -119, -118, -117, -115, -114 };
//				byte[] rawDESKey = { 128, 131, 133, 134, 137, 138, 139, 141, 142 };
//
////				SecretKeySpec cipherKey = new SecretKeySpec(rawDESKey, "DES");
//				KeyParameter cipherKey = new DesParameters(rawDESKey);
//
//				IBufferedCipher cipher = CipherUtilities.GetCipher("DES/ECB/NoPadding");
//				try
//				{
//					// According specification engineInit(int opmode, Key key,
//					// SecureRandom random) throws InvalidKeyException if the given
//					// key is inappropriate for initializing this cipher
//					cipher.Init(true, cipherKey);
//
//					Fail("failed exception test - no InvalidKeyException thrown");
//				}
//				catch (InvalidKeyException)
//				{
//					// ignore
//				}
//			}
//			catch (Exception e)
//			{
//				Fail("unexpected exception.", e);
//			}


            try
            {
                byte[] rawDESKey = { (byte)128, (byte)131, (byte)133, (byte)134,
                                     (byte)137, (byte)138, (byte)140, (byte)143 };

//				SecretKeySpec cipherKey = new SecretKeySpec(rawDESKey, "DES");
                KeyParameter cipherKey = new DesParameters(rawDESKey);

                IBufferedCipher ecipher = CipherUtilities.GetCipher("DES/ECB/PKCS5Padding");
                ecipher.Init(true, cipherKey);

                byte[] cipherText = new byte[0];
                try
                {
                    // According specification Method engineUpdate(byte[] input,
                    // int inputOffset, int inputLen, byte[] output, int
                    // outputOffset)
                    // throws ShortBufferException - if the given output buffer is
                    // too
                    // small to hold the result
//					ecipher.update(new byte[20], 0, 20, cipherText);
                    ecipher.ProcessBytes(new byte[20], 0, 20, cipherText, 0);

//					Fail("failed exception test - no ShortBufferException thrown");
                    Fail("failed exception test - no DataLengthException thrown");
                }
//				catch (ShortBufferException)
                catch (DataLengthException)
                {
                    // ignore
                }
            }
            catch (Exception e)
            {
                Fail("unexpected exception.", e);
            }

            // TODO Put back in
//			try
//			{
//				KeyGenerator keyGen = KeyGenerator.getInstance("DES");
//
//				keyGen.init((SecureRandom)null);
//
//				// According specification engineGenerateKey() doesn't throw any exceptions.
//
//				SecretKey key = keyGen.generateKey();
//				if (key == null)
//				{
//					Fail("key is null!");
//				}
//			}
//			catch (Exception e)
//			{
//				Fail("unexpected exception.", e);
//			}
//
//			try
//			{
//				AlgorithmParameters algParams = AlgorithmParameters.getInstance("DES");
//
//				algParams.init(new IvParameterSpec(new byte[8]));
//
//				// According specification engineGetEncoded() returns
//				// the parameters in their primary encoding format. The primary
//				// encoding
//				// format for parameters is ASN.1, if an ASN.1 specification for
//				// this type
//				// of parameters exists.
//				byte[] iv = algParams.getEncoded();
//
//				if (iv.Length!= 10)
//				{
//					Fail("parameters encoding wrong length - "  + iv.Length);
//				}
//			}
//			catch (Exception e)
//			{
//				Fail("unexpected exception.", e);
//			}

            try
            {
                try
                {
//					AlgorithmParameters algParams = AlgorithmParameters.getInstance("DES");

                    byte[] encoding = new byte[10];
                    encoding[0] = 3;
                    encoding[1] = 8;

//					algParams.init(encoding, "ASN.1");
                    ParameterUtilities.GetCipherParameters(
                        "AES",
                        ParameterUtilities.CreateKeyParameter("AES", new byte[16]),
                        Asn1Object.FromByteArray(encoding));

//					Fail("failed exception test - no IOException thrown");
                    Fail("failed exception test - no Exception thrown");
                }
//				catch (IOException)
                catch (ArgumentException)
                {
                    // okay
                }

//				try
//				{
//					IBufferedCipher c = CipherUtilities.GetCipher("DES");
//
//					Key k = new PublicKey()
//					{
//
//						public string getAlgorithm()
//						{
//							return "STUB";
//						}
//
//						public string getFormat()
//						{
//							return null;
//						}
//
//						public byte[] getEncoded()
//						{
//							return null;
//						}
//
//					};
//
//					c.Init(true, k);
//
//					Fail("failed exception test - no InvalidKeyException thrown for public key");
//				}
//				catch (InvalidKeyException e)
//				{
//					// okay
//				}
//
//				try
//				{
//					IBufferedCipher c = CipherUtilities.GetCipher("DES");
//
//					Key k = new PrivateKey()
//					{
//
//						public string getAlgorithm()
//						{
//							return "STUB";
//						}
//
//						public string getFormat()
//						{
//							return null;
//						}
//
//						public byte[] getEncoded()
//						{
//							return null;
//						}
//
//					};
//
//					c.Init(false, k);
//
//					Fail("failed exception test - no InvalidKeyException thrown for private key");
//				}
//				catch (InvalidKeyException e)
//				{
//					// okay
//				}
            }
            catch (Exception e)
            {
                Fail("unexpected exception.", e);
            }
        }
Exemple #16
0
        private void doTestException(
            string name,
            int ivLength)
        {
            try
            {
                byte[] key128 =
                {
                    (byte)128, (byte)131, (byte)133, (byte)134,
                    (byte)137, (byte)138, (byte)140, (byte)143,
                    (byte)128, (byte)131, (byte)133, (byte)134,
                    (byte)137, (byte)138, (byte)140, (byte)143
                };

                byte[] key256 =
                {
                    (byte)128, (byte)131, (byte)133, (byte)134,
                    (byte)137, (byte)138, (byte)140, (byte)143,
                    (byte)128, (byte)131, (byte)133, (byte)134,
                    (byte)137, (byte)138, (byte)140, (byte)143,
                    (byte)128, (byte)131, (byte)133, (byte)134,
                    (byte)137, (byte)138, (byte)140, (byte)143,
                    (byte)128, (byte)131, (byte)133, (byte)134,
                    (byte)137, (byte)138, (byte)140, (byte)143
                };

                byte[] keyBytes;
                if (name.Equals("HC256"))
                {
                    keyBytes = key256;
                }
                else
                {
                    keyBytes = key128;
                }

                KeyParameter cipherKey = ParameterUtilities.CreateKeyParameter(name, keyBytes);

                ICipherParameters cipherParams = cipherKey;
                if (ivLength > 0)
                {
                    cipherParams = new ParametersWithIV(cipherParams, new byte[ivLength]);
                }

                IBufferedCipher ecipher = CipherUtilities.GetCipher(name);
                ecipher.Init(true, cipherParams);

                byte[] cipherText = new byte[0];
                try
                {
                    // According specification Method engineUpdate(byte[] input,
                    // int inputOffset, int inputLen, byte[] output, int
                    // outputOffset)
                    // throws ShortBufferException - if the given output buffer is
                    // too
                    // small to hold the result
                    ecipher.ProcessBytes(new byte[20], 0, 20, cipherText, 0);

//					Fail("failed exception test - no ShortBufferException thrown");
                    Fail("failed exception test - no DataLengthException thrown");
                }
//				catch (ShortBufferException e)
                catch (DataLengthException)
                {
                    // ignore
                }

                // NB: The lightweight engine doesn't take public/private keys
//				try
//				{
//					IBufferedCipher c = CipherUtilities.GetCipher(name);
//
//					//                Key k = new PublicKey()
//					//                {
//					//
//					//                    public string getAlgorithm()
//					//                    {
//					//                        return "STUB";
//					//                    }
//					//
//					//                    public string getFormat()
//					//                    {
//					//                        return null;
//					//                    }
//					//
//					//                    public byte[] getEncoded()
//					//                    {
//					//                        return null;
//					//                    }
//					//
//					//                };
//					IAsymmetricKeyParameter k = new AsymmetricKeyParameter(false);
//					c.Init(true, k);
//
//					Fail("failed exception test - no InvalidKeyException thrown for public key");
//				}
//				catch (InvalidKeyException)
//				{
//					// okay
//				}
//
//				try
//				{
//					IBufferedCipher c = CipherUtilities.GetCipher(name);
//
//					//				Key k = new PrivateKey()
//					//                {
//					//
//					//                    public string getAlgorithm()
//					//                    {
//					//                        return "STUB";
//					//                    }
//					//
//					//                    public string getFormat()
//					//                    {
//					//                        return null;
//					//                    }
//					//
//					//                    public byte[] getEncoded()
//					//                    {
//					//                        return null;
//					//                    }
//					//
//					//                };
//
//					IAsymmetricKeyParameter k = new AsymmetricKeyParameter(true);
//					c.Init(false, k);
//
//					Fail("failed exception test - no InvalidKeyException thrown for private key");
//				}
//				catch (InvalidKeyException)
//				{
//					// okay
//				}
            }
            catch (Exception e)
            {
                Fail("unexpected exception.", e);
            }
        }
        /// <summary>Return the decrypted input stream, using the passed in passphrase.</summary>
        public Stream GetDataStream(
            char[] passPhrase)
        {
            IBufferedCipher c;

            try
            {
                SymmetricKeyAlgorithmTag alg = keyData.EncAlgorithm;

                string cName = PgpUtilities.GetSymmetricCipherName(alg);

                if (encData is SymmetricEncIntegrityPacket)
                {
                    cName += "/CFB/NoPadding";
                }
                else
                {
                    cName += "/OpenPGPCFB/NoPadding";
                }

                c = CipherUtilities.GetCipher(cName);
            }
            catch (PgpException e)
            {
                throw e;
            }
            catch (Exception e)
            {
                throw new PgpException("exception creating cipher", e);
            }

            if (c != null)
            {
                try
                {
                    KeyParameter key = PgpUtilities.MakeKeyFromPassPhrase(
                        keyData.EncAlgorithm, keyData.S2k, passPhrase);

                    byte[] iv = new byte[c.GetBlockSize()];

                    c.Init(false, new ParametersWithIV(key, iv));

                    encStream = BcpgInputStream.Wrap(new CipherStream(encData.GetInputStream(), c, null));

                    if (encData is SymmetricEncIntegrityPacket)
                    {
                        truncStream = new TruncatedStream(encStream);

                        string  digestName = PgpUtilities.GetDigestName(HashAlgorithmTag.Sha1);
                        IDigest digest     = DigestUtilities.GetDigest(digestName);

                        encStream = new DigestStream(truncStream, digest, null);
                    }

                    for (int i = 0; i != iv.Length; i++)
                    {
                        int ch = encStream.ReadByte();

                        if (ch < 0)
                        {
                            throw new EndOfStreamException("unexpected end of stream.");
                        }

                        iv[i] = (byte)ch;
                    }

                    int v1 = encStream.ReadByte();
                    int v2 = encStream.ReadByte();

                    if (v1 < 0 || v2 < 0)
                    {
                        throw new EndOfStreamException("unexpected end of stream.");
                    }


                    // Note: the oracle attack on the "quick check" bytes is not deemed
                    // a security risk for PBE (see PgpPublicKeyEncryptedData)

                    bool repeatCheckPassed =
                        iv[iv.Length - 2] == (byte)v1 &&
                        iv[iv.Length - 1] == (byte)v2;

                    // Note: some versions of PGP appear to produce 0 for the extra
                    // bytes rather than repeating the two previous bytes
                    bool zeroesCheckPassed =
                        v1 == 0 &&
                        v2 == 0;

                    if (!repeatCheckPassed && !zeroesCheckPassed)
                    {
                        throw new PgpDataValidationException("quick check failed.");
                    }


                    return(encStream);
                }
                catch (PgpException e)
                {
                    throw e;
                }
                catch (Exception e)
                {
                    throw new PgpException("Exception creating cipher", e);
                }
            }
            else
            {
                return(encData.GetInputStream());
            }
        }
Exemple #18
0
        private void doRunTest(
            string name,
            int ivLength)
        {
            string lCode = "ABCDEFGHIJKLMNOPQRSTUVWXY0123456789";

            string baseName = name;

            if (name.IndexOf('/') >= 0)
            {
                baseName = name.Substring(0, name.IndexOf('/'));
            }

            CipherKeyGenerator kGen = GeneratorUtilities.GetKeyGenerator(baseName);

            IBufferedCipher inCipher  = CipherUtilities.GetCipher(name);
            IBufferedCipher outCipher = CipherUtilities.GetCipher(name);
            KeyParameter    key       = ParameterUtilities.CreateKeyParameter(baseName, kGen.GenerateKey());
            MemoryStream    bIn       = new MemoryStream(Encoding.ASCII.GetBytes(lCode), false);
            MemoryStream    bOut      = new MemoryStream();

            // In the Java build, this IV would be implicitly created and then retrieved with getIV()
            ICipherParameters cipherParams = key;

            if (ivLength > 0)
            {
                cipherParams = new ParametersWithIV(cipherParams, new byte[ivLength]);
            }

            inCipher.Init(true, cipherParams);

            // TODO Should we provide GetIV() method on IBufferedCipher?
            //if (inCipher.getIV() != null)
            //{
            //	outCipher.Init(false, new ParametersWithIV(key, inCipher.getIV()));
            //}
            //else
            //{
            //	outCipher.Init(false, key);
            //}
            outCipher.Init(false, cipherParams);

            CipherStream cIn  = new CipherStream(bIn, inCipher, null);
            CipherStream cOut = new CipherStream(bOut, null, outCipher);

            int c;

            while ((c = cIn.ReadByte()) >= 0)
            {
                cOut.WriteByte((byte)c);
            }

            cIn.Close();

            cOut.Flush();
            cOut.Close();

            byte[] bs  = bOut.ToArray();
            string res = Encoding.ASCII.GetString(bs, 0, bs.Length);

            if (!res.Equals(lCode))
            {
                Fail("Failed - decrypted data doesn't match.");
            }
        }
        static void Main(string[] args)
        {
            var privateKey = "pX/BvdXXUdpC79mW/jWi10Z6PJb5SBY2+aqkR/qYOjqgakKsqZFKnl0kz10Ve+BP";
            var token      = "BDiRKNnPiPUb5oala31nkmCaXMB0iyWy3Q93p6fN7vPxEQSUlFVsInkJzPBBqmW1FUIY1KBA3BQb3W3Qv4akZ8kblqbmvupE/EJzPKbROZFBNvxpvVOHHgO2qadmHAjHSmnxUuxrpKxopWnOgyhzUx+mBUTao0pcEgqZFw0Y/qZIJPf1KusCMlz5TAhpjsw=";

            // #####
            // ##### Step 1
            // #####
            var decodedToken = Convert.FromBase64String(token);
            var decodedEphemeralPublicKey      = decodedToken.Take(97).ToArray();
            var encodedEphemeralPublicKeyCheck = Convert.ToBase64String(decodedEphemeralPublicKey);

            if (encodedEphemeralPublicKeyCheck != "BDiRKNnPiPUb5oala31nkmCaXMB0iyWy3Q93p6fN7vPxEQSUlFVsInkJzPBBqmW1FUIY1KBA3BQb3W3Qv4akZ8kblqbmvupE/EJzPKbROZFBNvxpvVOHHgO2qadmHAjHSg==")
            {
                throw new Exception("Public key check failed");
            }

            X9ECParameters        curveParams           = ECNamedCurveTable.GetByName("secp384r1");
            ECPoint               decodePoint           = curveParams.Curve.DecodePoint(decodedEphemeralPublicKey);
            ECDomainParameters    domainParams          = new ECDomainParameters(curveParams.Curve, curveParams.G, curveParams.N, curveParams.H, curveParams.GetSeed());
            ECPublicKeyParameters ecPublicKeyParameters = new ECPublicKeyParameters(decodePoint, domainParams);

            var x = ecPublicKeyParameters.Q.AffineXCoord.ToBigInteger();
            var y = ecPublicKeyParameters.Q.AffineYCoord.ToBigInteger();

            if (!x.Equals(new BigInteger("8706462696031173094919866327685737145866436939551712382591956952075131891462487598200779332295613073905587629438229")))
            {
                throw new Exception("X coord check failed");
            }

            if (!y.Equals(new BigInteger("10173258529327482491525749925661342501140613951412040971418641469645769857676705559747557238888921287857458976966474")))
            {
                throw new Exception("Y coord check failed");
            }

            Console.WriteLine("Step 1 complete");

            // #####
            // ##### Step 2
            // #####
            var privateKeyBytes        = Convert.FromBase64String(privateKey);
            var ecPrivateKeyParameters = new ECPrivateKeyParameters("ECDHC", new BigInteger(1, privateKeyBytes), domainParams);
            var privateKeyInfo         = PrivateKeyInfoFactory.CreatePrivateKeyInfo(ecPrivateKeyParameters);
            var ecPrivateKey           = (ECPrivateKeyParameters)PrivateKeyFactory.CreateKey(privateKeyInfo);

            IBasicAgreement agree = AgreementUtilities.GetBasicAgreement("ECDHC");

            agree.Init(ecPrivateKey);
            BigInteger sharedKey       = agree.CalculateAgreement(ecPublicKeyParameters);
            var        sharedKeyBytes  = sharedKey.ToByteArrayUnsigned();
            var        sharedKeyBase64 = Convert.ToBase64String(sharedKeyBytes);

            if (sharedKeyBase64 != "2lvSJsBO2keUHRfvPG6C1RMUmGpuDbdgNrZ9YD7RYnvAcfgq/fjeYr1p0hWABeif")
            {
                throw new Exception("Shared key check failed");
            }

            Console.WriteLine("Step 2 complete");

            // #####
            // ##### Step 3
            // #####
            var kdf2Bytes  = Kdf2(sharedKeyBytes, decodedEphemeralPublicKey);
            var kdf2Base64 = Convert.ToBase64String(kdf2Bytes);

            if (kdf2Base64 != "mAzkYatDlz4SzrCyM23NhgL/+mE3eGgfUz9h1CFPhZOtXequzN3Q8w+B5GE2eU5g")
            {
                throw new Exception("Kdf2 failed");
            }

            Console.WriteLine("Step 3 complete");

            // #####
            // ##### Step 4
            // #####
            var decryptionKeyBytes = kdf2Bytes.Take(32).ToArray();
            var decryptionIvBytes  = kdf2Bytes.Skip(32).ToArray();

            var decryptionKeyBase64 = Convert.ToBase64String(decryptionKeyBytes);
            var decryptionIvBase64  = Convert.ToBase64String(decryptionIvBytes);

            if (decryptionKeyBase64 != "mAzkYatDlz4SzrCyM23NhgL/+mE3eGgfUz9h1CFPhZM=")
            {
                throw new Exception("Decryption key check failed");
            }

            if (decryptionIvBase64 != "rV3qrszd0PMPgeRhNnlOYA==")
            {
                throw new Exception("Decryption iv check failed");
            }

            var encryptedDataBytes = decodedToken.Skip(97).Take(decodedToken.Length - 113).ToArray();
            var tagBytes           = decodedToken.Skip(decodedToken.Length - 16).ToArray();

            var encryptedDataBase64 = Convert.ToBase64String(encryptedDataBytes);
            var tagBase64           = Convert.ToBase64String(tagBytes);

            if (encryptedDataBase64 != "afFS7GukrGilac6DKHNTH6YFRNqjSlwSCpkXDRj+")
            {
                throw new Exception("Encrypted data check failed");
            }

            if (tagBase64 != "pkgk9/Uq6wIyXPlMCGmOzA==")
            {
                throw new Exception("Tag check failed");
            }

            KeyParameter     keyParam   = ParameterUtilities.CreateKeyParameter("AES", decryptionKeyBytes);
            ParametersWithIV parameters = new ParametersWithIV(keyParam, decryptionIvBytes);
            IBufferedCipher  cipher     = CipherUtilities.GetCipher("AES/GCM/NoPadding");

            cipher.Init(false, parameters);
            var resultBytes  = cipher.DoFinal(encryptedDataBytes.Concat(tagBytes).ToArray());
            var resultBase64 = Convert.ToBase64String(resultBytes);
            var resultString = Strings.FromByteArray(resultBytes);

            if (resultString != "xXTi32iZwrQ6O8Sy6r1isKwF6Ff1Py")
            {
                throw new Exception("Decryption failed");
            }

            Console.WriteLine("Step 4 complete");
            Console.WriteLine(resultString);

            Console.WriteLine();
            Console.WriteLine("Done... press any key to finish");
            Console.ReadLine();
        }
        private static TLConfigSimple DecryptSimpleConfig(string dataString)
        {
            TLConfigSimple result = null;

#if !WIN_RT
            var base64Chars = dataString.Where(ch =>
            {
                var isGoodBase64 =
                    (ch == '+') || (ch == '=') || (ch == '/') ||
                    (ch >= 'a' && ch <= 'z') ||
                    (ch >= 'A' && ch <= 'Z') ||
                    (ch >= '0' && ch <= '9');

                return(isGoodBase64);
            }).ToArray();

            var       cleanDataString = new string(base64Chars);
            const int kGoodSizeBase64 = 344;
            if (cleanDataString.Length != kGoodSizeBase64)
            {
                Log(string.Format("Bad base64 size {0} required {1}", cleanDataString.Length, kGoodSizeBase64));
                return(null);
            }
            byte[] data = null;
            try
            {
                data = Convert.FromBase64String(cleanDataString);
            }
            catch (Exception ex)
            {
                Log("Bad base64 bytes");

                return(null);
            }
            const int kGoodSizeData = 256;
            if (data.Length != kGoodSizeData)
            {
                Log(string.Format("Bad data size {0} required {1}", data.Length, kGoodSizeData));

                return(null);
            }

            var xml = "<RSAKeyValue><Modulus>yr+18Rex2ohtVy8sroGPBwXD3DOoKCSpjDqYoXgCqB7ioln4eDCFfOBUlfXUEvM/fnKCpF46VkAftlb4VuPDeQSS/ZxZYEGqHaywlroVnXHIjgqoxiAd192xRGreuXIaUKmkwlM9JID9WS2jUsTpzQ91L8MEPLJ/4zrBwZua8W5fECwCCh2c9G5IzzBm+otMS/YKwmR1olzRCyEkyAEjXWqBI9Ftv5eG8m0VkBzOG655WIYdyV0HfDK/NWcvGqa0w/nriMD6mDjKOryamw0OP9QuYgMN0C9xMW9y8SmP4h92OAWodTYgY1hZCxdv6cs5UnW9+PWvS+WIbkh+GaWYxw==</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";

            var provider = new RSACryptoServiceProvider();
            provider.FromXmlString(xml);
            var parameters = provider.ExportParameters(false);
            var modulus    = parameters.Modulus;
            var exponent   = parameters.Exponent;

            var dataBI     = new BigInteger(data.Reverse().Concat(new byte[] { 0x00 }).ToArray());
            var exponentBI = new BigInteger(exponent.Reverse().Concat(new byte[] { 0x00 }).ToArray());
            var modulusBI  = new BigInteger(modulus.Reverse().Concat(new byte[] { 0x00 }).ToArray());

            var authKey = BigInteger.ModPow(dataBI, exponentBI, modulusBI).ToByteArray();
            if (authKey[authKey.Length - 1] == 0x00)
            {
                authKey = authKey.SubArray(0, authKey.Length - 1);
            }

            authKey = authKey.Reverse().ToArray();
            if (authKey.Length > 256)
            {
                var correctedAuth = new byte[256];
                Array.Copy(authKey, authKey.Length - 256, correctedAuth, 0, 256);
                authKey = correctedAuth;
            }
            else if (authKey.Length < 256)
            {
                var correctedAuth = new byte[256];
                Array.Copy(authKey, 0, correctedAuth, 256 - authKey.Length, authKey.Length);
                for (var i = 0; i < 256 - authKey.Length; i++)
                {
                    authKey[i] = 0;
                }
                authKey = correctedAuth;
            }

            var key           = authKey.SubArray(0, 32);
            var iv            = authKey.SubArray(16, 16);
            var encryptedData = authKey.SubArray(32, authKey.Length - 32);

            var cipher = CipherUtilities.GetCipher("AES/CBC/NOPADDING");
            var param  = new KeyParameter(key);
            cipher.Init(false, new ParametersWithIV(param, iv));
            var decryptedData = cipher.DoFinal(encryptedData);

            const int kDigestSize = 16;
            var       hash        = Utils.ComputeSHA256(decryptedData.SubArray(0, 208));
            for (var i = 0; i < kDigestSize; i++)
            {
                if (hash[i] != decryptedData[208 + i])
                {
                    Log("Bad digest");
                    return(null);
                }
            }

            var position = 4;
            var length   = BitConverter.ToInt32(decryptedData, 0);
            if (length <= 0 || length > 208 || length % 4 != 0)
            {
                Log(string.Format("Bad length {0}", length));
                return(null);
            }
            try
            {
                result = TLObject.GetObject <TLConfigSimple>(decryptedData, ref position);
            }
            catch (Exception ex)
            {
                Log("Could not read configSimple");
                return(null);
            }

            if (position != length)
            {
                Log(string.Format("Bad read length {0} shoud be {1}", position, length));
                return(null);
            }
#endif

            return(result);
        }
        private Stream Open(
            Stream outStream,
            AlgorithmIdentifier encAlgID,
            ICipherParameters cipherParameters,
            Asn1EncodableVector recipientInfos)
        {
            try
            {
                //
                // ContentInfo
                //
                BerSequenceGenerator cGen = new BerSequenceGenerator(outStream);

                cGen.AddObject(CmsObjectIdentifiers.EnvelopedData);

                //
                // Encrypted Data
                //
                BerSequenceGenerator envGen = new BerSequenceGenerator(
                    cGen.GetRawOutputStream(), 0, true);

                envGen.AddObject(this.Version);

                Asn1Generator recipGen = _berEncodeRecipientSet
                                        ?       (Asn1Generator) new BerSetGenerator(envGen.GetRawOutputStream())
                                        :       new DerSetGenerator(envGen.GetRawOutputStream());

                foreach (Asn1Encodable ae in recipientInfos)
                {
                    recipGen.AddObject(ae);
                }

                recipGen.Close();

                BerSequenceGenerator eiGen = new BerSequenceGenerator(
                    envGen.GetRawOutputStream());

                eiGen.AddObject(PkcsObjectIdentifiers.Data);
                eiGen.AddObject(encAlgID);

                BerOctetStringGenerator octGen = new BerOctetStringGenerator(
                    eiGen.GetRawOutputStream(), 0, false);
                Stream octetOutputStream = octGen.GetOctetOutputStream(_bufferSize);

                IBufferedCipher cipher = CipherUtilities.GetCipher(encAlgID.ObjectID);
                cipher.Init(true, new ParametersWithRandom(cipherParameters, rand));
                CipherStream cOut = new CipherStream(octetOutputStream, null, cipher);

                return(new CmsEnvelopedDataOutputStream(cOut, cGen, envGen, eiGen));
            }
            catch (SecurityUtilityException e)
            {
                throw new CmsException("couldn't create cipher.", e);
            }
            catch (InvalidKeyException e)
            {
                throw new CmsException("key invalid in message.", e);
            }
            catch (IOException e)
            {
                throw new CmsException("exception decoding algorithm parameters.", e);
            }
        }
        /// <inheritdoc/>
        protected override async Task OnOpenAsync(CancellationToken token = default)
        {
            _logger?.LogInformation($"Opening session channel with endpoint '{RemoteEndpoint.EndpointUrl}'.");
            _logger?.LogInformation($"SecurityPolicy: '{RemoteEndpoint.SecurityPolicyUri}'.");
            _logger?.LogInformation($"SecurityMode: '{RemoteEndpoint.SecurityMode}'.");
            _logger?.LogInformation($"UserIdentity: '{UserIdentity}'.");

            await base.OnOpenAsync(token).ConfigureAwait(false);

            token.ThrowIfCancellationRequested();

            // if SessionId is provided then we skip the CreateSessionRequest and go directly to (re)ActivateSession.
            // requires from previous Session: SessionId, AuthenticationToken, RemoteNonce
            if (SessionId == null)
            {
                var localNonce           = GetNextNonce(_nonceLength);
                var localCertificate     = LocalCertificate;
                var createSessionRequest = new CreateSessionRequest
                {
                    ClientDescription       = LocalDescription,
                    EndpointUrl             = RemoteEndpoint.EndpointUrl,
                    SessionName             = LocalDescription.ApplicationName,
                    ClientNonce             = localNonce,
                    ClientCertificate       = localCertificate,
                    RequestedSessionTimeout = _options.SessionTimeout,
                    MaxResponseMessageSize  = RemoteMaxMessageSize
                };

                var createSessionResponse = await this.CreateSessionAsync(createSessionRequest).ConfigureAwait(false);

                SessionId           = createSessionResponse.SessionId;
                AuthenticationToken = createSessionResponse.AuthenticationToken;
                RemoteNonce         = createSessionResponse.ServerNonce;

                // verify the server's certificate is the same as the certificate from the selected endpoint.
                ThrowOnInvalidSessionServerCertificate(createSessionResponse.ServerCertificate);

                // verify the server's signature.
                ISigner?verifier = null;
                bool    verified = false;

                switch (RemoteEndpoint.SecurityPolicyUri)
                {
                case SecurityPolicyUris.Basic128Rsa15:
                case SecurityPolicyUris.Basic256:
                    verifier = SignerUtilities.GetSigner("SHA-1withRSA");
                    verifier.Init(false, RemotePublicKey);
                    verifier.BlockUpdate(localCertificate, 0, localCertificate !.Length);
                    verifier.BlockUpdate(localNonce, 0, localNonce !.Length);
                    verified = verifier.VerifySignature(createSessionResponse.ServerSignature !.Signature);
                    break;

                case SecurityPolicyUris.Basic256Sha256:
                case SecurityPolicyUris.Aes128_Sha256_RsaOaep:
                    verifier = SignerUtilities.GetSigner("SHA-256withRSA");
                    verifier.Init(false, RemotePublicKey);
                    verifier.BlockUpdate(localCertificate, 0, localCertificate !.Length);
                    verifier.BlockUpdate(localNonce, 0, localNonce !.Length);
                    verified = verifier.VerifySignature(createSessionResponse.ServerSignature !.Signature);
                    break;

                case SecurityPolicyUris.Aes256_Sha256_RsaPss:
                    verifier = SignerUtilities.GetSigner("SHA-256withRSAandMGF1");
                    verifier.Init(false, RemotePublicKey);
                    verifier.BlockUpdate(localCertificate, 0, localCertificate !.Length);
                    verifier.BlockUpdate(localNonce, 0, localNonce !.Length);
                    verified = verifier.VerifySignature(createSessionResponse.ServerSignature !.Signature);
                    break;

                default:
                    verified = true;
                    break;
                }

                verifier = null;
                if (!verified)
                {
                    throw new ServiceResultException(StatusCodes.BadApplicationSignatureInvalid, "Server did not provide a correct signature for the nonce data provided by the client.");
                }
            }

            // create client signature
            SignatureData?clientSignature = null;
            ISigner?      signer          = null;

            switch (RemoteEndpoint.SecurityPolicyUri)
            {
            case SecurityPolicyUris.Basic128Rsa15:
            case SecurityPolicyUris.Basic256:
                signer = SignerUtilities.GetSigner("SHA-1withRSA");
                signer.Init(true, LocalPrivateKey);
                signer.BlockUpdate(RemoteEndpoint.ServerCertificate, 0, RemoteEndpoint.ServerCertificate !.Length);
                signer.BlockUpdate(RemoteNonce, 0, RemoteNonce !.Length);
                clientSignature = new SignatureData
                {
                    Signature = signer.GenerateSignature(),
                    Algorithm = _rsaSha1Signature,
                };

                break;

            case SecurityPolicyUris.Basic256Sha256:
            case SecurityPolicyUris.Aes128_Sha256_RsaOaep:
                signer = SignerUtilities.GetSigner("SHA-256withRSA");
                signer.Init(true, LocalPrivateKey);
                signer.BlockUpdate(RemoteEndpoint.ServerCertificate, 0, RemoteEndpoint.ServerCertificate !.Length);
                signer.BlockUpdate(RemoteNonce, 0, RemoteNonce !.Length);
                clientSignature = new SignatureData
                {
                    Signature = signer.GenerateSignature(),
                    Algorithm = _rsaSha256Signature,
                };

                break;

            case SecurityPolicyUris.Aes256_Sha256_RsaPss:
                signer = SignerUtilities.GetSigner("SHA-256withRSAandMGF1");
                signer.Init(true, LocalPrivateKey);
                signer.BlockUpdate(RemoteEndpoint.ServerCertificate, 0, RemoteEndpoint.ServerCertificate !.Length);
                signer.BlockUpdate(RemoteNonce, 0, RemoteNonce !.Length);
                clientSignature = new SignatureData
                {
                    Signature = signer.GenerateSignature(),
                    Algorithm = _rsaPssSha256Signature,
                };

                break;

            default:
                clientSignature = new SignatureData();
                break;
            }

            signer = null;

            // supported UserIdentityToken types are AnonymousIdentityToken, UserNameIdentityToken, IssuedIdentityToken, X509IdentityToken
            UserIdentityToken?identityToken  = null;
            SignatureData?    tokenSignature = null;

            // if UserIdentity type is IssuedIdentity
            if (UserIdentity is IssuedIdentity issuedIdentity)
            {
                var tokenPolicy = RemoteEndpoint.UserIdentityTokens.FirstOrDefault(t => t?.TokenType == UserTokenType.IssuedToken);
                if (tokenPolicy == null)
                {
                    throw new ServiceResultException(StatusCodes.BadIdentityTokenRejected);
                }

                int             plainTextLength = issuedIdentity.TokenData.Length + RemoteNonce !.Length;
                IBufferedCipher encryptor;
                byte[]          cipherText;
                int             pos;

                var secPolicyUri = tokenPolicy.SecurityPolicyUri ?? RemoteEndpoint.SecurityPolicyUri;
                switch (secPolicyUri)
                {
                case SecurityPolicyUris.Basic128Rsa15:
                    encryptor = CipherUtilities.GetCipher("RSA//PKCS1Padding");
                    encryptor.Init(true, RemotePublicKey);
                    cipherText    = new byte[encryptor.GetOutputSize(4 + plainTextLength)];
                    pos           = encryptor.ProcessBytes(BitConverter.GetBytes(plainTextLength), cipherText, 0);
                    pos           = encryptor.ProcessBytes(issuedIdentity.TokenData, cipherText, pos);
                    pos           = encryptor.DoFinal(RemoteNonce, cipherText, pos);
                    identityToken = new IssuedIdentityToken
                    {
                        TokenData           = cipherText,
                        EncryptionAlgorithm = _rsaV15KeyWrap,
                        PolicyId            = tokenPolicy.PolicyId
                    };

                    break;

                case SecurityPolicyUris.Basic256:
                case SecurityPolicyUris.Basic256Sha256:
                case SecurityPolicyUris.Aes128_Sha256_RsaOaep:
                    encryptor = CipherUtilities.GetCipher("RSA//OAEPPADDING");
                    encryptor.Init(true, RemotePublicKey);
                    cipherText    = new byte[encryptor.GetOutputSize(4 + plainTextLength)];
                    pos           = encryptor.ProcessBytes(BitConverter.GetBytes(plainTextLength), cipherText, 0);
                    pos           = encryptor.ProcessBytes(issuedIdentity.TokenData, cipherText, pos);
                    pos           = encryptor.DoFinal(RemoteNonce, cipherText, pos);
                    identityToken = new IssuedIdentityToken
                    {
                        TokenData           = cipherText,
                        EncryptionAlgorithm = _rsaOaepKeyWrap,
                        PolicyId            = tokenPolicy.PolicyId
                    };

                    break;

                case SecurityPolicyUris.Aes256_Sha256_RsaPss:
                    encryptor = CipherUtilities.GetCipher("RSA//OAEPWITHSHA256ANDMGF1PADDING");
                    encryptor.Init(true, RemotePublicKey);
                    cipherText    = new byte[encryptor.GetOutputSize(4 + plainTextLength)];
                    pos           = encryptor.ProcessBytes(BitConverter.GetBytes(plainTextLength), cipherText, 0);
                    pos           = encryptor.ProcessBytes(issuedIdentity.TokenData, cipherText, pos);
                    pos           = encryptor.DoFinal(RemoteNonce, cipherText, pos);
                    identityToken = new IssuedIdentityToken
                    {
                        TokenData           = cipherText,
                        EncryptionAlgorithm = _rsaOaepSha256KeyWrap,
                        PolicyId            = tokenPolicy.PolicyId
                    };

                    break;

                default:
                    identityToken = new IssuedIdentityToken
                    {
                        TokenData           = issuedIdentity.TokenData,
                        EncryptionAlgorithm = null,
                        PolicyId            = tokenPolicy.PolicyId
                    };
                    break;
                }

                tokenSignature = new SignatureData();
            }

            // if UserIdentity type is X509Identity
            else if (UserIdentity is X509Identity x509Identity)
            {
                var tokenPolicy = RemoteEndpoint.UserIdentityTokens.FirstOrDefault(t => t?.TokenType == UserTokenType.Certificate);
                if (tokenPolicy == null)
                {
                    throw new ServiceResultException(StatusCodes.BadIdentityTokenRejected);
                }

                identityToken = new X509IdentityToken {
                    CertificateData = x509Identity.Certificate?.GetEncoded(), PolicyId = tokenPolicy.PolicyId
                };

                var secPolicyUri = tokenPolicy.SecurityPolicyUri ?? RemoteEndpoint.SecurityPolicyUri;
                switch (secPolicyUri)
                {
                case SecurityPolicyUris.Basic128Rsa15:
                case SecurityPolicyUris.Basic256:
                    signer = SignerUtilities.GetSigner("SHA-1withRSA");
                    signer.Init(true, x509Identity.PrivateKey);
                    signer.BlockUpdate(RemoteEndpoint.ServerCertificate, 0, RemoteEndpoint.ServerCertificate !.Length);
                    signer.BlockUpdate(RemoteNonce, 0, RemoteNonce !.Length);
                    tokenSignature = new SignatureData
                    {
                        Signature = signer.GenerateSignature(),
                        Algorithm = _rsaSha1Signature,
                    };

                    break;

                case SecurityPolicyUris.Basic256Sha256:
                case SecurityPolicyUris.Aes128_Sha256_RsaOaep:
                    signer = SignerUtilities.GetSigner("SHA-256withRSA");
                    signer.Init(true, x509Identity.PrivateKey);
                    signer.BlockUpdate(RemoteEndpoint.ServerCertificate, 0, RemoteEndpoint.ServerCertificate !.Length);
                    signer.BlockUpdate(RemoteNonce, 0, RemoteNonce !.Length);
                    tokenSignature = new SignatureData
                    {
                        Signature = signer.GenerateSignature(),
                        Algorithm = _rsaSha256Signature,
                    };
                    break;

                case SecurityPolicyUris.Aes256_Sha256_RsaPss:
                    signer = SignerUtilities.GetSigner("SHA-256withRSAandMGF1");
                    signer.Init(true, x509Identity.PrivateKey);
                    signer.BlockUpdate(RemoteEndpoint.ServerCertificate, 0, RemoteEndpoint.ServerCertificate !.Length);
                    signer.BlockUpdate(RemoteNonce, 0, RemoteNonce !.Length);
                    tokenSignature = new SignatureData
                    {
                        Signature = signer.GenerateSignature(),
                        Algorithm = _rsaSha256Signature,
                    };
                    break;

                default:
                    tokenSignature = new SignatureData();
                    break;
                }

                signer = null;
            }

            // if UserIdentity type is UserNameIdentity
            else if (UserIdentity is UserNameIdentity userNameIdentity)
            {
                var tokenPolicy = RemoteEndpoint.UserIdentityTokens.FirstOrDefault(t => t?.TokenType == UserTokenType.UserName);
                if (tokenPolicy == null)
                {
                    throw new ServiceResultException(StatusCodes.BadIdentityTokenRejected);
                }

                byte[] passwordBytes = userNameIdentity.Password != null?System.Text.Encoding.UTF8.GetBytes(userNameIdentity.Password) : new byte[0];

                int             plainTextLength = passwordBytes.Length + RemoteNonce !.Length;
                IBufferedCipher encryptor;
                byte[]          cipherText;
                int             pos;

                var secPolicyUri = tokenPolicy.SecurityPolicyUri ?? RemoteEndpoint.SecurityPolicyUri;
                switch (secPolicyUri)
                {
                case SecurityPolicyUris.Basic128Rsa15:
                    encryptor = CipherUtilities.GetCipher("RSA//PKCS1Padding");
                    encryptor.Init(true, RemotePublicKey);
                    cipherText    = new byte[encryptor.GetOutputSize(4 + plainTextLength)];
                    pos           = encryptor.ProcessBytes(BitConverter.GetBytes(plainTextLength), cipherText, 0);
                    pos           = encryptor.ProcessBytes(passwordBytes, cipherText, pos);
                    pos           = encryptor.DoFinal(RemoteNonce, cipherText, pos);
                    identityToken = new UserNameIdentityToken
                    {
                        UserName            = userNameIdentity.UserName,
                        Password            = cipherText,
                        EncryptionAlgorithm = _rsaV15KeyWrap,
                        PolicyId            = tokenPolicy.PolicyId
                    };

                    break;

                case SecurityPolicyUris.Basic256:
                case SecurityPolicyUris.Basic256Sha256:
                case SecurityPolicyUris.Aes128_Sha256_RsaOaep:
                    encryptor = CipherUtilities.GetCipher("RSA//OAEPPADDING");
                    encryptor.Init(true, RemotePublicKey);
                    cipherText    = new byte[encryptor.GetOutputSize(4 + plainTextLength)];
                    pos           = encryptor.ProcessBytes(BitConverter.GetBytes(plainTextLength), cipherText, 0);
                    pos           = encryptor.ProcessBytes(passwordBytes, cipherText, pos);
                    pos           = encryptor.DoFinal(RemoteNonce, cipherText, pos);
                    identityToken = new UserNameIdentityToken
                    {
                        UserName            = userNameIdentity.UserName,
                        Password            = cipherText,
                        EncryptionAlgorithm = _rsaOaepKeyWrap,
                        PolicyId            = tokenPolicy.PolicyId
                    };

                    break;

                case SecurityPolicyUris.Aes256_Sha256_RsaPss:
                    encryptor = CipherUtilities.GetCipher("RSA//OAEPWITHSHA256ANDMGF1PADDING");
                    encryptor.Init(true, RemotePublicKey);
                    cipherText    = new byte[encryptor.GetOutputSize(4 + plainTextLength)];
                    pos           = encryptor.ProcessBytes(BitConverter.GetBytes(plainTextLength), cipherText, 0);
                    pos           = encryptor.ProcessBytes(passwordBytes, cipherText, pos);
                    pos           = encryptor.DoFinal(RemoteNonce, cipherText, pos);
                    identityToken = new UserNameIdentityToken
                    {
                        UserName            = userNameIdentity.UserName,
                        Password            = cipherText,
                        EncryptionAlgorithm = _rsaOaepSha256KeyWrap,
                        PolicyId            = tokenPolicy.PolicyId
                    };

                    break;

                default:
                    identityToken = new UserNameIdentityToken
                    {
                        UserName            = userNameIdentity.UserName,
                        Password            = passwordBytes,
                        EncryptionAlgorithm = null,
                        PolicyId            = tokenPolicy.PolicyId
                    };
                    break;
                }

                tokenSignature = new SignatureData();
            }

            // if UserIdentity type is AnonymousIdentity or null
            else
            {
                var tokenPolicy = RemoteEndpoint.UserIdentityTokens.FirstOrDefault(t => t?.TokenType == UserTokenType.Anonymous);
                if (tokenPolicy == null)
                {
                    throw new ServiceResultException(StatusCodes.BadIdentityTokenRejected);
                }

                identityToken = new AnonymousIdentityToken {
                    PolicyId = tokenPolicy.PolicyId
                };
                tokenSignature = new SignatureData();
            }

            var activateSessionRequest = new ActivateSessionRequest
            {
                ClientSignature    = clientSignature,
                LocaleIds          = new[] { CultureInfo.CurrentUICulture.TwoLetterISOLanguageName },
                UserIdentityToken  = identityToken,
                UserTokenSignature = tokenSignature
            };
            var activateSessionResponse = await this.ActivateSessionAsync(activateSessionRequest).ConfigureAwait(false);

            RemoteNonce = activateSessionResponse.ServerNonce;

            // fetch namespace array, etc.
            var readValueIds = new ReadValueId[]
            {
                new ReadValueId
                {
                    NodeId      = NodeId.Parse(VariableIds.Server_NamespaceArray),
                    AttributeId = AttributeIds.Value
                },
                new ReadValueId
                {
                    NodeId      = NodeId.Parse(VariableIds.Server_ServerArray),
                    AttributeId = AttributeIds.Value
                }
            };
            var readRequest = new ReadRequest
            {
                NodesToRead = readValueIds
            };

            var readResponse = await this.ReadAsync(readRequest).ConfigureAwait(false);

            if (readResponse.Results?.Length == 2)
            {
                if (readResponse.Results[0] is { } res0&& StatusCode.IsGood(res0.StatusCode))
                {
                    if (res0.GetValueOrDefault <string[]>() is { } namespaceUris)
                    {
                        NamespaceUris = namespaceUris;
                    }
                }

                if (readResponse.Results[1] is { } res1&& StatusCode.IsGood(res1.StatusCode))
                {
                    if (res1.GetValueOrDefault <string[]>() is { } serverUris)
                    {
                        ServerUris = serverUris;
                    }
                }
            }

            // create the keep alive subscription.
            var subscriptionRequest = new CreateSubscriptionRequest
            {
                RequestedPublishingInterval = 1000f,
                RequestedMaxKeepAliveCount  = 5,
                RequestedLifetimeCount      = 120,
                PublishingEnabled           = true,
            };
            var subscriptionResponse = await this.CreateSubscriptionAsync(subscriptionRequest).ConfigureAwait(false);

            // link up the dataflow blocks
            var id        = subscriptionResponse.SubscriptionId;
            var linkToken = this.LinkTo(_actionBlock, pr => pr.SubscriptionId == id);

            // start publishing.
            _stateMachineTask = Task.Run(() => StateMachineAsync(_stateMachineCts.Token));
        }
Exemple #23
0
        public override void PerformTest()
        {
            byte[] input = Hex.Decode("1234567890abcdefabcdef1234567890fedbca098765");

            //
            // DES
            //
            IBufferedCipher cEnc = CipherUtilities.GetCipher("DES/CBC/PKCS7Padding");

            cEnc.Init(
                true,
                new ParametersWithIV(
                    new DesParameters(Hex.Decode("30e69252758e5346")),
                    Hex.Decode("7c1c1ab9c454a688")));

            byte[] outBytes = cEnc.DoFinal(input);
            char[] password = "******".ToCharArray();

            IBufferedCipher cDec = makePbeCipherUsingParam(
                "PBEWithSHA1AndDES",
                false,
                password,
                Hex.Decode("7d60435f02e9e0ae"),
                2048);

            byte[] inBytes = cDec.DoFinal(outBytes);

            if (!AreEqual(input, inBytes))
            {
                Fail("DES failed");
            }

            cDec = makePbeCipherWithoutParam(
                "PBEWithSHA1AndDES",
                false,
                password,
                Hex.Decode("7d60435f02e9e0ae"),
                2048);

            inBytes = cDec.DoFinal(outBytes);

            if (!AreEqual(input, inBytes))
            {
                Fail("DES failed without param");
            }

            //
            // DESede
            //
            cEnc = CipherUtilities.GetCipher("DESede/CBC/PKCS7Padding");

            cEnc.Init(
                true,
                new ParametersWithIV(
                    new DesParameters(Hex.Decode("732f2d33c801732b7206756cbd44f9c1c103ddd97c7cbe8e")),
                    Hex.Decode("b07bf522c8d608b8")));

            outBytes = cEnc.DoFinal(input);

            cDec = makePbeCipherUsingParam(
                "PBEWithSHAAnd3-KeyTripleDES-CBC",
                false,
                password,
                Hex.Decode("7d60435f02e9e0ae"),
                2048);

            inBytes = cDec.DoFinal(outBytes);

            if (!AreEqual(input, inBytes))
            {
                Fail("DESede failed");
            }

            //
            // 40Bit RC2
            //
            cEnc = CipherUtilities.GetCipher("RC2/CBC/PKCS7Padding");

            cEnc.Init(
                true,
                new ParametersWithIV(
                    new RC2Parameters(Hex.Decode("732f2d33c8")),
                    Hex.Decode("b07bf522c8d608b8")));

            outBytes = cEnc.DoFinal(input);

            cDec = makePbeCipherUsingParam(
                "PBEWithSHAAnd40BitRC2-CBC",
                false,
                password,
                Hex.Decode("7d60435f02e9e0ae"),
                2048);

            inBytes = cDec.DoFinal(outBytes);

            if (!AreEqual(input, inBytes))
            {
                Fail("RC2 failed");
            }

            //
            // 128bit RC4
            //
            cEnc = CipherUtilities.GetCipher("RC4");

            cEnc.Init(
                true,
                ParameterUtilities.CreateKeyParameter("RC4", Hex.Decode("732f2d33c801732b7206756cbd44f9c1")));

            outBytes = cEnc.DoFinal(input);

            cDec = makePbeCipherUsingParam(
                "PBEWithSHAAnd128BitRC4",
                false,
                password,
                Hex.Decode("7d60435f02e9e0ae"),
                2048);

            inBytes = cDec.DoFinal(outBytes);

            if (!AreEqual(input, inBytes))
            {
                Fail("RC4 failed");
            }

            cDec = makePbeCipherWithoutParam(
                "PBEWithSHAAnd128BitRC4",
                false,
                password,
                Hex.Decode("7d60435f02e9e0ae"),
                2048);

            inBytes = cDec.DoFinal(outBytes);

            if (!AreEqual(input, inBytes))
            {
                Fail("RC4 failed without param");
            }

            for (int i = 0; i != pkcs12Tests.Length; i++)
            {
                pkcs12Tests[i].PerformTest();
            }

            for (int i = 0; i != openSSLTests.Length; i++)
            {
                openSSLTests[i].PerformTest();
            }

            doTestPbeHMac("PBEWithHMacSHA1", hMac1);
            doTestPbeHMac("PBEWithHMacRIPEMD160", hMac2);
        }
Exemple #24
0
        private byte[] ExtractKeyData(
            char[] passPhrase)
        {
            SymmetricKeyAlgorithmTag alg = secret.EncAlgorithm;

            byte[] encData = secret.GetSecretKeyData();

            if (alg == SymmetricKeyAlgorithmTag.Null)
            {
                return(encData);
            }

            byte[]          data;
            IBufferedCipher c = null;

            try
            {
                string cName = PgpUtilities.GetSymmetricCipherName(alg);
                c = CipherUtilities.GetCipher(cName + "/CFB/NoPadding");
            }
            catch (Exception e)
            {
                throw new PgpException("Exception creating cipher", e);
            }

            // TODO Factor this block out as 'encryptData'
            try
            {
                KeyParameter key = PgpUtilities.MakeKeyFromPassPhrase(secret.EncAlgorithm, secret.S2k, passPhrase);
                byte[]       iv  = secret.GetIV();

                if (secret.PublicKeyPacket.Version == 4)
                {
                    c.Init(false, new ParametersWithIV(key, iv));

                    data = c.DoFinal(encData);

                    bool   useSha1 = secret.S2kUsage == SecretKeyPacket.UsageSha1;
                    byte[] check   = Checksum(useSha1, data, (useSha1) ? data.Length - 20 : data.Length - 2);

                    for (int i = 0; i != check.Length; i++)
                    {
                        if (check[i] != data[data.Length - check.Length + i])
                        {
                            throw new PgpException("Checksum mismatch at " + i + " of " + check.Length);
                        }
                    }
                }
                else // version 2 or 3, RSA only.
                {
                    data = new byte[encData.Length];

                    //
                    // read in the four numbers
                    //
                    int pos = 0;

                    for (int i = 0; i != 4; i++)
                    {
                        c.Init(false, new ParametersWithIV(key, iv));

                        int encLen = (((encData[pos] << 8) | (encData[pos + 1] & 0xff)) + 7) / 8;

                        data[pos]     = encData[pos];
                        data[pos + 1] = encData[pos + 1];
                        pos          += 2;

                        c.DoFinal(encData, pos, encLen, data, pos);
                        pos += encLen;

                        if (i != 3)
                        {
                            Array.Copy(encData, pos - iv.Length, iv, 0, iv.Length);
                        }
                    }

                    //
                    // verify Checksum
                    //
                    int cs     = ((encData[pos] << 8) & 0xff00) | (encData[pos + 1] & 0xff);
                    int calcCs = 0;
                    for (int j = 0; j < data.Length - 2; j++)
                    {
                        calcCs += data[j] & 0xff;
                    }

                    calcCs &= 0xffff;
                    if (calcCs != cs)
                    {
                        throw new PgpException("Checksum mismatch: passphrase wrong, expected "
                                               + cs.ToString("X")
                                               + " found " + calcCs.ToString("X"));
                    }
                }

                return(data);
            }
            catch (PgpException e)
            {
                throw e;
            }
            catch (Exception e)
            {
                throw new PgpException("Exception decrypting key", e);
            }
        }
Exemple #25
0
        internal Stream DoGetDataStream(byte[] rawPassPhrase, bool clearPassPhrase)
        {
            try
            {
                SymmetricKeyAlgorithmTag keyAlgorithm = keyData.EncAlgorithm;

                KeyParameter key = PgpUtilities.DoMakeKeyFromPassPhrase(
                    keyAlgorithm, keyData.S2k, rawPassPhrase, clearPassPhrase);

                byte[] secKeyData = keyData.GetSecKeyData();
                if (secKeyData != null && secKeyData.Length > 0)
                {
                    IBufferedCipher keyCipher = CipherUtilities.GetCipher(
                        PgpUtilities.GetSymmetricCipherName(keyAlgorithm) + "/CFB/NoPadding");

                    keyCipher.Init(false,
                                   new ParametersWithIV(key, new byte[keyCipher.GetBlockSize()]));

                    byte[] keyBytes = keyCipher.DoFinal(secKeyData);

                    keyAlgorithm = (SymmetricKeyAlgorithmTag)keyBytes[0];

                    key = ParameterUtilities.CreateKeyParameter(
                        PgpUtilities.GetSymmetricCipherName(keyAlgorithm),
                        keyBytes, 1, keyBytes.Length - 1);
                }


                IBufferedCipher c = CreateStreamCipher(keyAlgorithm);

                byte[] iv = new byte[c.GetBlockSize()];

                c.Init(false, new ParametersWithIV(key, iv));

                encStream = BcpgInputStream.Wrap(new CipherStream(encData.GetInputStream(), c, null));

                if (encData is SymmetricEncIntegrityPacket)
                {
                    truncStream = new TruncatedStream(encStream);

                    string  digestName = PgpUtilities.GetDigestName(HashAlgorithmTag.Sha1);
                    IDigest digest     = DigestUtilities.GetDigest(digestName);

                    encStream = new DigestStream(truncStream, digest, null);
                }

                if (Streams.ReadFully(encStream, iv, 0, iv.Length) < iv.Length)
                {
                    throw new EndOfStreamException("unexpected end of stream.");
                }

                int v1 = encStream.ReadByte();
                int v2 = encStream.ReadByte();

                if (v1 < 0 || v2 < 0)
                {
                    throw new EndOfStreamException("unexpected end of stream.");
                }


                // Note: the oracle attack on the "quick check" bytes is not deemed
                // a security risk for PBE (see PgpPublicKeyEncryptedData)

                bool repeatCheckPassed =
                    iv[iv.Length - 2] == (byte)v1 &&
                    iv[iv.Length - 1] == (byte)v2;

                // Note: some versions of PGP appear to produce 0 for the extra
                // bytes rather than repeating the two previous bytes
                bool zeroesCheckPassed =
                    v1 == 0 &&
                    v2 == 0;

                if (!repeatCheckPassed && !zeroesCheckPassed)
                {
                    throw new PgpDataValidationException("quick check failed.");
                }


                return(encStream);
            }
            catch (PgpException e)
            {
                throw e;
            }
            catch (Exception e)
            {
                throw new PgpException("Exception creating cipher", e);
            }
        }
        /// <exception cref="Sharpen.NoSuchAlgorithmException"></exception>
        public override byte[] EncryptDigest(byte[] digestValue, DigestAlgorithm digestAlgo
                                             , IDssPrivateKeyEntry keyEntry)
        {
            try
            {
                ByteArrayOutputStream digestInfo = new ByteArrayOutputStream();
                //jbonilla: cambio de enum a clase.
                if (digestAlgo.Equals(DigestAlgorithm.SHA1))
                {
                    digestInfo.Write(Constants.SHA1_DIGEST_INFO_PREFIX);
                }
                else
                {
                    if (digestAlgo.Equals(DigestAlgorithm.SHA256))
                    {
                        digestInfo.Write(Constants.SHA256_DIGEST_INFO_PREFIX);
                    }
                    else
                    {
                        if (digestAlgo.Equals(DigestAlgorithm.SHA256))
                        {
                            digestInfo.Write(Constants.SHA512_DIGEST_INFO_PREFIX);
                        }
                    }
                }
                digestInfo.Write(digestValue);
                //Sharpen.Cipher cipher = Sharpen.Cipher.GetInstance(keyEntry.GetSignatureAlgorithm
                //    ().GetPadding());
                IBufferedCipher cipher = CipherUtilities.GetCipher(keyEntry.GetSignatureAlgorithm
                                                                       ().GetPadding());

                //cipher.Init(Sharpen.Cipher.ENCRYPT_MODE, ((KSPrivateKeyEntry)keyEntry).GetPrivateKey
                //    ());
                cipher.Init(true, ((KSPrivateKeyEntry)keyEntry).PrivateKey);
                return(cipher.DoFinal(digestInfo.ToByteArray()));
            }
            catch (IOException e)
            {
                // Writing in a ByteArrayOutputStream. Should never happens.
                throw new RuntimeException(e);
            }

            /*catch (NoSuchPaddingException e)
             * {
             *  throw new RuntimeException(e);
             * }*/
            catch (InvalidKeyException e)
            {
                throw new RuntimeException(e);
            }

            /*catch (IllegalBlockSizeException e)
             * {
             *  throw new RuntimeException(e);
             * }
             * catch (BadPaddingException)
             * {
             *  // More likely the password is not good.
             *  throw new BadPasswordException(BadPasswordException.MSG.PKCS12_BAD_PASSWORD);
             * }*/
        }
        /// <summary>
        /// <p>
        /// If buffer is non null stream assumed to be partial, otherwise the length will be used
        /// to output a fixed length packet.
        /// </p>
        /// <p>
        /// The stream created can be closed off by either calling Close()
        /// on the stream or Close() on the generator. Closing the returned
        /// stream does not close off the Stream parameter <c>outStr</c>.
        /// </p>
        /// </summary>
        private Stream Open(
            Stream outStr,
            long length,
            byte[]      buffer)
        {
            if (cOut != null)
            {
                throw new InvalidOperationException("generator already in open state");
            }
            if (methods.Count == 0)
            {
                throw new InvalidOperationException("No encryption methods specified");
            }
            if (outStr == null)
            {
                throw new ArgumentNullException("outStr");
            }

            pOut = new BcpgOutputStream(outStr);

            KeyParameter key;

            if (methods.Count == 1)
            {
                if (methods[0] is PbeMethod)
                {
                    PbeMethod m = (PbeMethod)methods[0];

                    key = m.GetKey();
                }
                else
                {
                    key = PgpUtilities.MakeRandomKey(defAlgorithm, rand);

                    byte[]    sessionInfo = CreateSessionInfo(defAlgorithm, key);
                    PubMethod m           = (PubMethod)methods[0];

                    try
                    {
                        m.AddSessionInfo(sessionInfo, rand);
                    }
                    catch (Exception e)
                    {
                        throw new PgpException("exception encrypting session key", e);
                    }
                }

                pOut.WritePacket((ContainedPacket)methods[0]);
            }
            else // multiple methods
            {
                key = PgpUtilities.MakeRandomKey(defAlgorithm, rand);
                byte[] sessionInfo = CreateSessionInfo(defAlgorithm, key);

                for (int i = 0; i != methods.Count; i++)
                {
                    EncMethod m = (EncMethod)methods[i];

                    try
                    {
                        m.AddSessionInfo(sessionInfo, rand);
                    }
                    catch (Exception e)
                    {
                        throw new PgpException("exception encrypting session key", e);
                    }

                    pOut.WritePacket(m);
                }
            }

            string cName = PgpUtilities.GetSymmetricCipherName(defAlgorithm);

            if (cName == null)
            {
                throw new PgpException("null cipher specified");
            }

            try
            {
                if (withIntegrityPacket)
                {
                    cName += "/CFB/NoPadding";
                }
                else
                {
                    cName += "/OpenPGPCFB/NoPadding";
                }

                c = CipherUtilities.GetCipher(cName);

                // TODO Confirm the IV should be all zero bytes (not inLineIv - see below)
                byte[] iv = new byte[c.GetBlockSize()];
                c.Init(true, new ParametersWithRandom(new ParametersWithIV(key, iv), rand));

                if (buffer == null)
                {
                    //
                    // we have to Add block size + 2 for the Generated IV and + 1 + 22 if integrity protected
                    //
                    if (withIntegrityPacket)
                    {
                        pOut = new BcpgOutputStream(outStr, PacketTag.SymmetricEncryptedIntegrityProtected, length + c.GetBlockSize() + 2 + 1 + 22);
                        pOut.WriteByte(1);        // version number
                    }
                    else
                    {
                        pOut = new BcpgOutputStream(outStr, PacketTag.SymmetricKeyEncrypted, length + c.GetBlockSize() + 2, oldFormat);
                    }
                }
                else
                {
                    if (withIntegrityPacket)
                    {
                        pOut = new BcpgOutputStream(outStr, PacketTag.SymmetricEncryptedIntegrityProtected, buffer);
                        pOut.WriteByte(1);        // version number
                    }
                    else
                    {
                        pOut = new BcpgOutputStream(outStr, PacketTag.SymmetricKeyEncrypted, buffer);
                    }
                }

                int    blockSize = c.GetBlockSize();
                byte[] inLineIv  = new byte[blockSize + 2];
                rand.NextBytes(inLineIv, 0, blockSize);
                Array.Copy(inLineIv, inLineIv.Length - 4, inLineIv, inLineIv.Length - 2, 2);

                Stream myOut = cOut = new CipherStream(pOut, null, c);

                if (withIntegrityPacket)
                {
                    string  digestName = PgpUtilities.GetDigestName(HashAlgorithmTag.Sha1);
                    IDigest digest     = DigestUtilities.GetDigest(digestName);
                    myOut = digestOut = new DigestStream(myOut, null, digest);
                }

                myOut.Write(inLineIv, 0, inLineIv.Length);

                return(new WrappedGeneratorStream(this, myOut));
            }
            catch (Exception e)
            {
                throw new PgpException("Exception creating cipher", e);
            }
        }
Exemple #28
0
        private void doTest(
            string algorithm,
            byte[]      input,
            byte[]      output)
        {
            KeyParameter       key = null;
            CipherKeyGenerator keyGen;
            SecureRandom       rand;
            IBufferedCipher    inCipher = null, outCipher = null;

            byte[]       iv = null;
            CipherStream cIn, cOut;
            MemoryStream bIn, bOut;

            rand = new FixedSecureRandom();

            string[] parts = algorithm.ToUpper(CultureInfo.InvariantCulture).Split('/');
            string   baseAlgorithm = parts[0];
            string   mode  = parts.Length > 1 ? parts[1] : null;

            try
            {
                keyGen = GeneratorUtilities.GetKeyGenerator(baseAlgorithm);

                // TODO Add Algorithm property to CipherKeyGenerator?
//				if (!keyGen.getAlgorithm().Equals(baseAlgorithm))
//				{
//					Fail("wrong key generator returned!");
//				}

                // TODO Add new Init method to CipherKeyGenerator?
//				keyGen.Init(rand);
                keyGen.Init(new KeyGenerationParameters(rand, keyGen.DefaultStrength));

                byte[] keyBytes = keyGen.GenerateKey();

                if (algorithm.StartsWith("RC5"))
                {
                    key = new RC5Parameters(keyBytes, rc5Rounds);
                }
                else
                {
                    key = ParameterUtilities.CreateKeyParameter(baseAlgorithm, keyBytes);
                }

                inCipher  = CipherUtilities.GetCipher(algorithm);
                outCipher = CipherUtilities.GetCipher(algorithm);

                if (!inCipher.AlgorithmName.ToUpper(CultureInfo.InvariantCulture).StartsWith(baseAlgorithm))
                {
                    Fail("wrong cipher returned!");
                }

                ICipherParameters parameters = key;

                int ivLength = GetIVLength(algorithm);

                if (ivLength > 0)
                {
                    if (baseAlgorithm == "RC2")
                    {
                        iv = rc2IV;
                    }
                    else if (baseAlgorithm == "RC5")
                    {
                        iv = rc5IV;
                    }
                    else if (baseAlgorithm == "RC5-64")
                    {
                        iv = rc564IV;
                    }
                    else
                    {
                        // NB: rand always generates same values each test run
                        iv = SecureRandom.GetNextBytes(rand, ivLength);
                    }

                    parameters = new ParametersWithIV(key, iv);
                }

                // NB: 'rand' still needed e.g. for some paddings
                parameters = new ParametersWithRandom(parameters, rand);

                outCipher.Init(true, parameters);
            }
            catch (Exception e)
            {
                Fail("" + algorithm + " failed initialisation - " + e.ToString(), e);
            }

            //
            // grab the iv if there is one
            //
            try
            {
                // The Java version set this implicitly, but we set it explicity
                //byte[] iv = outCipher.getIV();

                if (iv != null)
                {
                    // TODO Examine short IV handling for these FIPS-compliant modes in Java build
                    if (mode.StartsWith("CCM") ||
                        mode.StartsWith("CFB") ||
                        mode.StartsWith("CTR") ||
                        mode.StartsWith("EAX") ||
                        mode.StartsWith("GCM") ||
                        mode.StartsWith("GOFB") ||
                        mode.StartsWith("OCB") ||
                        mode.StartsWith("OFB") ||
                        mode.StartsWith("OPENPGPCFB") ||
                        mode.StartsWith("SIC"))
                    {
                        // These modes automatically pad out the IV if it is short
                    }
                    else
                    {
                        try
                        {
                            byte[] nIv = new byte[iv.Length - 1];
                            inCipher.Init(false, new ParametersWithIV(key, nIv));
                            Fail("failed to pick up short IV");
                        }
                        //catch (InvalidAlgorithmParameterException e)
                        catch (ArgumentException)
                        {
                            // ignore - this is what we want...
                        }
                    }

                    //IvParameterSpec spec = new IvParameterSpec(iv);
                    inCipher.Init(false, new ParametersWithIV(key, iv));
                }
                else
                {
                    inCipher.Init(false, key);
                }
            }
            catch (Exception e)
            {
                Fail("" + algorithm + " failed initialisation - " + e.ToString());
            }

            //
            // encryption pass
            //
            bOut = new MemoryStream();
            cOut = new CipherStream(bOut, null, outCipher);

            try
            {
                for (int i = 0; i != input.Length / 2; i++)
                {
                    cOut.WriteByte(input[i]);
                }
                cOut.Write(input, input.Length / 2, input.Length - input.Length / 2);
                cOut.Close();
            }
            catch (IOException e)
            {
                Fail("" + algorithm + " failed encryption - " + e.ToString());
            }

            byte[] bytes = bOut.ToArray();

            if (!AreEqual(bytes, output))
            {
                Fail("" + algorithm + " failed encryption - expected "
                     + Hex.ToHexString(output) + " got "
                     + Hex.ToHexString(bytes));
            }

            //
            // decryption pass
            //
            bIn = new MemoryStream(bytes, false);
            cIn = new CipherStream(bIn, inCipher, null);

            try
            {
                BinaryReader dIn = new BinaryReader(cIn);

                bytes = new byte[input.Length];

                for (int i = 0; i != input.Length / 2; i++)
                {
                    bytes[i] = dIn.ReadByte();
                }

                int    remaining = bytes.Length - input.Length / 2;
                byte[] extra     = dIn.ReadBytes(remaining);
                if (extra.Length < remaining)
                {
                    throw new EndOfStreamException();
                }
                extra.CopyTo(bytes, input.Length / 2);
            }
            catch (Exception e)
            {
                Fail("" + algorithm + " failed decryption - " + e.ToString());
            }

            if (!AreEqual(bytes, input))
            {
                Fail("" + algorithm + " failed decryption - expected "
                     + Hex.ToHexString(input) + " got "
                     + Hex.ToHexString(bytes));
            }
        }
Exemple #29
0
        public void DoTest(
            int strength,
            byte[]      keyBytes,
            byte[]      input,
            byte[]      output)
        {
            KeyParameter key = ParameterUtilities.CreateKeyParameter("SM4", keyBytes);

            IBufferedCipher inCipher  = CipherUtilities.GetCipher("SM4/ECB/NoPadding");
            IBufferedCipher outCipher = CipherUtilities.GetCipher("SM4/ECB/NoPadding");

            try
            {
                outCipher.Init(true, key);
            }
            catch (Exception e)
            {
                Fail("SM4 failed initialisation - " + e, e);
            }

            try
            {
                inCipher.Init(false, key);
            }
            catch (Exception e)
            {
                Fail("SM4 failed initialisation - " + e, e);
            }

            //
            // encryption pass
            //
            MemoryStream bOut = new MemoryStream();

            CipherStream cOut = new CipherStream(bOut, null, outCipher);

            try
            {
                for (int i = 0; i != input.Length / 2; i++)
                {
                    cOut.WriteByte(input[i]);
                }
                cOut.Write(input, input.Length / 2, input.Length - input.Length / 2);
                cOut.Close();
            }
            catch (IOException e)
            {
                Fail("SM4 failed encryption - " + e, e);
            }

            byte[] bytes = bOut.ToArray();

            if (!AreEqual(bytes, output))
            {
                Fail("SM4 failed encryption - expected "
                     + Hex.ToHexString(output) + " got "
                     + Hex.ToHexString(bytes));
            }

            //
            // decryption pass
            //
            MemoryStream bIn = new MemoryStream(bytes, false);

            CipherStream cIn = new CipherStream(bIn, inCipher, null);

            try
            {
//				DataInputStream dIn = new DataInputStream(cIn);
                BinaryReader dIn = new BinaryReader(cIn);

                bytes = new byte[input.Length];

                for (int i = 0; i != input.Length / 2; i++)
                {
//					bytes[i] = (byte)dIn.read();
                    bytes[i] = dIn.ReadByte();
                }

                int remaining = bytes.Length - input.Length / 2;
//				dIn.readFully(bytes, input.Length / 2, remaining);
                byte[] extra = dIn.ReadBytes(remaining);
                if (extra.Length < remaining)
                {
                    throw new EndOfStreamException();
                }
                extra.CopyTo(bytes, input.Length / 2);
            }
            catch (Exception e)
            {
                Fail("SM4 failed encryption - " + e, e);
            }

            if (!AreEqual(bytes, input))
            {
                Fail("SM4 failed decryption - expected "
                     + Hex.ToHexString(input) + " got "
                     + Hex.ToHexString(bytes));
            }
        }
 public IBufferedCipher GetCipher()
 {
     return(CipherUtilities.GetCipher("AES/GCM/NoPadding"));
 }