예제 #1
0
 /// <summary>Create a key pair from a PgpPrivateKey and a PgpPublicKey.</summary>
 /// <param name="pub">The public key.</param>
 /// <param name="priv">The private key.</param>
 public PgpKeyPair(
     PgpPublicKey pub,
     PgpPrivateKey priv)
 {
     this.pub  = pub;
     this.priv = priv;
 }
예제 #2
0
        /// <summary>Initialise the generator for signing.</summary>
        public void InitSign(
            int sigType,
            PgpPrivateKey key,
            SecureRandom random)
        {
            this.privKey       = key;
            this.signatureType = sigType;

            try
            {
                ICipherParameters cp = key.Key;
                if (random != null)
                {
                    cp = new ParametersWithRandom(key.Key, random);
                }

                sig.Init(true, cp);
            }
            catch (InvalidKeyException e)
            {
                throw new PgpException("invalid key.", e);
            }

            dig.Reset();
            lastb = 0;
        }
        /// <summary>
        /// Return the algorithm code for the symmetric algorithm used to encrypt the data.
        /// </summary>
        public SymmetricKeyAlgorithmTag GetSymmetricAlgorithm(
            PgpPrivateKey privKey)
        {
            byte[] sessionData = RecoverSessionData(privKey);

            return((SymmetricKeyAlgorithmTag)sessionData[0]);
        }
예제 #4
0
 public PgpKeyPair(
     PublicKeyAlgorithmTag algorithm,
     AsymmetricKeyParameter pubKey,
     AsymmetricKeyParameter privKey,
     DateTime time)
 {
     this.pub  = new PgpPublicKey(algorithm, pubKey, time);
     this.priv = new PgpPrivateKey(pub.KeyId, pub.PublicKeyPacket, privKey);
 }
예제 #5
0
 /// <summary>Initialise the generator for signing.</summary>
 public void InitSign(
     int sigType,
     PgpPrivateKey key)
 {
     InitSign(sigType, key, null);
 }
        /// <summary>Return the decrypted data stream for the packet.</summary>
        public Stream GetDataStream(
            PgpPrivateKey privKey)
        {
            byte[] sessionData = RecoverSessionData(privKey);

            if (!ConfirmCheckSum(sessionData))
            {
                throw new PgpKeyValidationException("key checksum failed");
            }

            SymmetricKeyAlgorithmTag symmAlg = (SymmetricKeyAlgorithmTag)sessionData[0];

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

            IBufferedCipher cipher;
            string          cipherName = PgpUtilities.GetSymmetricCipherName(symmAlg);
            string          cName      = cipherName;

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

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

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

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

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

                encStream = BcpgInputStream.Wrap(new CipherStream(encData.GetInputStream(), cipher, 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);
            }
        }
        private byte[] RecoverSessionData(PgpPrivateKey privKey)
        {
            byte[][] secKeyData = keyData.GetEncSessionKey();

            if (keyData.Algorithm == PublicKeyAlgorithmTag.ECDH)
            {
                ECDHPublicBcpgKey ecKey    = (ECDHPublicBcpgKey)privKey.PublicKeyPacket.Key;
                X9ECParameters    x9Params = ECKeyPairGenerator.FindECCurveByOid(ecKey.CurveOid);

                byte[] enc = secKeyData[0];

                int    pLen = ((((enc[0] & 0xff) << 8) + (enc[1] & 0xff)) + 7) / 8;
                byte[] pEnc = new byte[pLen];

                Array.Copy(enc, 2, pEnc, 0, pLen);

                byte[] keyEnc = new byte[enc[pLen + 2]];

                Array.Copy(enc, 2 + pLen + 1, keyEnc, 0, keyEnc.Length);

                ECPoint publicPoint = x9Params.Curve.DecodePoint(pEnc);

                ECPrivateKeyParameters privKeyParams = (ECPrivateKeyParameters)privKey.Key;
                ECPoint S = publicPoint.Multiply(privKeyParams.D).Normalize();

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

                IWrapper w = PgpUtilities.CreateWrapper(ecKey.SymmetricKeyAlgorithm);
                w.Init(false, key);

                return(PgpPad.UnpadSessionData(w.Unwrap(keyEnc, 0, keyEnc.Length)));
            }

            IBufferedCipher cipher = GetKeyCipher(keyData.Algorithm);

            try
            {
                cipher.Init(false, privKey.Key);
            }
            catch (InvalidKeyException e)
            {
                throw new PgpException("error setting asymmetric cipher", e);
            }

            if (keyData.Algorithm == PublicKeyAlgorithmTag.RsaEncrypt ||
                keyData.Algorithm == PublicKeyAlgorithmTag.RsaGeneral)
            {
                byte[] bi = secKeyData[0];

                cipher.ProcessBytes(bi, 2, bi.Length - 2);
            }
            else
            {
                ElGamalPrivateKeyParameters k = (ElGamalPrivateKeyParameters)privKey.Key;
                int size = (k.Parameters.P.BitLength + 7) / 8;

                ProcessEncodedMpi(cipher, size, secKeyData[0]);
                ProcessEncodedMpi(cipher, size, secKeyData[1]);
            }

            try
            {
                return(cipher.DoFinal());
            }
            catch (Exception e)
            {
                throw new PgpException("exception decrypting secret key", e);
            }
        }