Beispiel #1
0
        private static byte[] GetDValue(Stream inputStream, byte[] rawPassPhrase, bool clearPassPhrase, string curveName)
        {
            //IL_008a: Unknown result type (might be due to invalid IL or missing references)
            //IL_0091: Expected O, but got Unknown
            SXprUtilities.SkipOpenParenthesis(inputStream);
            string text = SXprUtilities.ReadString(inputStream, inputStream.ReadByte());

            if (text.Equals("protected"))
            {
                SXprUtilities.ReadString(inputStream, inputStream.ReadByte());
                SXprUtilities.SkipOpenParenthesis(inputStream);
                S2k    s2k = SXprUtilities.ParseS2k(inputStream);
                byte[] iv  = SXprUtilities.ReadBytes(inputStream, inputStream.ReadByte());
                SXprUtilities.SkipCloseParenthesis(inputStream);
                byte[]       array  = SXprUtilities.ReadBytes(inputStream, inputStream.ReadByte());
                KeyParameter key    = PgpUtilities.DoMakeKeyFromPassPhrase(SymmetricKeyAlgorithmTag.Aes128, s2k, rawPassPhrase, clearPassPhrase);
                byte[]       array2 = RecoverKeyData(SymmetricKeyAlgorithmTag.Aes128, "/CBC/NoPadding", key, iv, array, 0, array.Length);
                Stream       val    = (Stream) new MemoryStream(array2, false);
                SXprUtilities.SkipOpenParenthesis(val);
                SXprUtilities.SkipOpenParenthesis(val);
                SXprUtilities.SkipOpenParenthesis(val);
                SXprUtilities.ReadString(val, val.ReadByte());
                return(SXprUtilities.ReadBytes(val, val.ReadByte()));
            }
            throw new PgpException("protected block not found");
        }
Beispiel #2
0
        private static byte[] EncryptKeyDataV3(byte[] rawKeyData, SymmetricKeyAlgorithmTag encAlgorithm, byte[] rawPassPhrase, bool clearPassPhrase, SecureRandom random, out S2k s2k, out byte[] iv)
        {
            s2k = null;
            iv  = null;
            KeyParameter key = PgpUtilities.DoMakeKeyFromPassPhrase(encAlgorithm, s2k, rawPassPhrase, clearPassPhrase);

            byte[] array = new byte[rawKeyData.Length];
            int    num   = 0;

            for (int i = 0; i != 4; i++)
            {
                int num2 = (((rawKeyData[num] << 8) | (rawKeyData[num + 1] & 0xFF)) + 7) / 8;
                array[num]     = rawKeyData[num];
                array[num + 1] = rawKeyData[num + 1];
                byte[] array2;
                if (i == 0)
                {
                    array2 = EncryptData(encAlgorithm, key, rawKeyData, num + 2, num2, random, ref iv);
                }
                else
                {
                    byte[] iv2 = Arrays.CopyOfRange(array, num - iv.Length, num);
                    array2 = EncryptData(encAlgorithm, key, rawKeyData, num + 2, num2, random, ref iv2);
                }
                global::System.Array.Copy((global::System.Array)array2, 0, (global::System.Array)array, num + 2, array2.Length);
                num += 2 + num2;
            }
            array[num]     = rawKeyData[num];
            array[num + 1] = rawKeyData[num + 1];
            return(array);
        }
Beispiel #3
0
        private static byte[] EncryptKeyDataV4(byte[] rawKeyData, SymmetricKeyAlgorithmTag encAlgorithm, HashAlgorithmTag hashAlgorithm, byte[] rawPassPhrase, bool clearPassPhrase, SecureRandom random, out S2k s2k, out byte[] iv)
        {
            s2k = PgpUtilities.GenerateS2k(hashAlgorithm, 96, random);
            KeyParameter key = PgpUtilities.DoMakeKeyFromPassPhrase(encAlgorithm, s2k, rawPassPhrase, clearPassPhrase);

            iv = null;
            return(EncryptData(encAlgorithm, key, rawKeyData, 0, rawKeyData.Length, random, ref iv));
        }
Beispiel #4
0
 internal Stream DoGetDataStream(byte[] rawPassPhrase, bool clearPassPhrase)
 {
     //IL_012b: Unknown result type (might be due to invalid IL or missing references)
     //IL_015a: Unknown result type (might be due to invalid IL or missing references)
     try
     {
         SymmetricKeyAlgorithmTag symmetricKeyAlgorithmTag = keyData.EncAlgorithm;
         KeyParameter             parameters = PgpUtilities.DoMakeKeyFromPassPhrase(symmetricKeyAlgorithmTag, keyData.S2k, rawPassPhrase, clearPassPhrase);
         byte[] secKeyData = keyData.GetSecKeyData();
         if (secKeyData != null && secKeyData.Length > 0)
         {
             IBufferedCipher cipher = CipherUtilities.GetCipher(PgpUtilities.GetSymmetricCipherName(symmetricKeyAlgorithmTag) + "/CFB/NoPadding");
             cipher.Init(forEncryption: false, new ParametersWithIV(parameters, new byte[cipher.GetBlockSize()]));
             byte[] array = cipher.DoFinal(secKeyData);
             symmetricKeyAlgorithmTag = (SymmetricKeyAlgorithmTag)array[0];
             parameters = ParameterUtilities.CreateKeyParameter(PgpUtilities.GetSymmetricCipherName(symmetricKeyAlgorithmTag), array, 1, array.Length - 1);
         }
         IBufferedCipher bufferedCipher = CreateStreamCipher(symmetricKeyAlgorithmTag);
         byte[]          array2         = new byte[bufferedCipher.GetBlockSize()];
         bufferedCipher.Init(forEncryption: false, new ParametersWithIV(parameters, array2));
         encStream = (Stream)(object)BcpgInputStream.Wrap((Stream)(object)new CipherStream((Stream)(object)encData.GetInputStream(), bufferedCipher, null));
         if (encData is SymmetricEncIntegrityPacket)
         {
             truncStream = new TruncatedStream(encStream);
             string  digestName = PgpUtilities.GetDigestName(HashAlgorithmTag.Sha1);
             IDigest digest     = DigestUtilities.GetDigest(digestName);
             encStream = (Stream)(object)new DigestStream((Stream)(object)truncStream, digest, null);
         }
         if (Streams.ReadFully(encStream, array2, 0, array2.Length) < array2.Length)
         {
             throw new EndOfStreamException("unexpected end of stream.");
         }
         int num  = encStream.ReadByte();
         int num2 = encStream.ReadByte();
         if (num < 0 || num2 < 0)
         {
             throw new EndOfStreamException("unexpected end of stream.");
         }
         bool flag  = array2[array2.Length - 2] == (byte)num && array2[array2.Length - 1] == (byte)num2;
         bool flag2 = num == 0 && num2 == 0;
         if (!flag && !flag2)
         {
             throw new PgpDataValidationException("quick check failed.");
         }
         return(encStream);
     }
     catch (PgpException ex)
     {
         throw ex;
     }
     catch (global::System.Exception exception)
     {
         throw new PgpException("Exception creating cipher", exception);
     }
 }
Beispiel #5
0
        internal void DoAddMethod(byte[] rawPassPhrase, bool clearPassPhrase, HashAlgorithmTag s2kDigest)
        {
            S2k s2k = PgpUtilities.GenerateS2k(s2kDigest, 0x60, rand);

            methods.Add(new PbeMethod(defAlgorithm, s2k, PgpUtilities.DoMakeKeyFromPassPhrase(defAlgorithm, s2k, rawPassPhrase, clearPassPhrase)));
        }
Beispiel #6
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);
            }
        }
Beispiel #7
0
        private byte[] ExtractKeyData(byte[] rawPassPhrase, bool clearPassPhrase)
        {
            SymmetricKeyAlgorithmTag encAlgorithm = secret.EncAlgorithm;

            byte[] secretKeyData = secret.GetSecretKeyData();
            if (encAlgorithm == SymmetricKeyAlgorithmTag.Null)
            {
                return(secretKeyData);
            }
            try
            {
                KeyParameter key = PgpUtilities.DoMakeKeyFromPassPhrase(secret.EncAlgorithm, secret.S2k, rawPassPhrase, clearPassPhrase);
                byte[]       iV  = secret.GetIV();
                byte[]       array;
                if (secret.PublicKeyPacket.Version >= 4)
                {
                    array = RecoverKeyData(encAlgorithm, "/CFB/NoPadding", key, iV, secretKeyData, 0, secretKeyData.Length);
                    bool   flag   = secret.S2kUsage == 254;
                    byte[] array2 = Checksum(flag, array, flag ? (array.Length - 20) : (array.Length - 2));
                    for (int i = 0; i != array2.Length; i++)
                    {
                        if (array2[i] != array[array.Length - array2.Length + i])
                        {
                            throw new PgpException(string.Concat(new object[4] {
                                "Checksum mismatch at ", i, " of ", array2.Length
                            }));
                        }
                    }
                }
                else
                {
                    array = new byte[secretKeyData.Length];
                    iV    = Arrays.Clone(iV);
                    int num = 0;
                    for (int j = 0; j != 4; j++)
                    {
                        int num2 = (((secretKeyData[num] << 8) | (secretKeyData[num + 1] & 0xFF)) + 7) / 8;
                        array[num]     = secretKeyData[num];
                        array[num + 1] = secretKeyData[num + 1];
                        num           += 2;
                        byte[] array3 = RecoverKeyData(encAlgorithm, "/CFB/NoPadding", key, iV, secretKeyData, num, num2);
                        global::System.Array.Copy((global::System.Array)array3, 0, (global::System.Array)array, num, num2);
                        num += num2;
                        if (j != 3)
                        {
                            global::System.Array.Copy((global::System.Array)secretKeyData, num - iV.Length, (global::System.Array)iV, 0, iV.Length);
                        }
                    }
                    array[num]     = secretKeyData[num];
                    array[num + 1] = secretKeyData[num + 1];
                    int num3 = ((secretKeyData[num] << 8) & 0xFF00) | (secretKeyData[num + 1] & 0xFF);
                    int num4 = 0;
                    for (int k = 0; k < num; k++)
                    {
                        num4 += array[k] & 0xFF;
                    }
                    num4 &= 0xFFFF;
                    if (num4 != num3)
                    {
                        throw new PgpException("Checksum mismatch: passphrase wrong, expected " + num3.ToString("X") + " found " + num4.ToString("X"));
                    }
                }
                return(array);
            }
            catch (PgpException ex)
            {
                throw ex;
            }
            catch (global::System.Exception exception)
            {
                throw new PgpException("Exception decrypting key", exception);
            }
        }