public PgpObjectFactory( Stream inputStream) { this.bcpgIn = BcpgInputStream.Wrap(inputStream); }
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); } }
public PgpSecretKeyRing( Stream inputStream) { this.keys = Platform.CreateArrayList(); this.extraPubKeys = Platform.CreateArrayList(); BcpgInputStream bcpgInput = BcpgInputStream.Wrap(inputStream); PacketTag initialTag = bcpgInput.NextPacketTag(); if (initialTag != PacketTag.SecretKey && initialTag != PacketTag.SecretSubkey) { throw new IOException("secret key ring doesn't start with secret key tag: " + "tag 0x" + ((int)initialTag).ToString("X")); } SecretKeyPacket secret = (SecretKeyPacket)bcpgInput.ReadPacket(); // // ignore GPG comment packets if found. // while (bcpgInput.NextPacketTag() == PacketTag.Experimental2) { bcpgInput.ReadPacket(); } TrustPacket trust = ReadOptionalTrustPacket(bcpgInput); // revocation and direct signatures IList keySigs = ReadSignaturesAndTrust(bcpgInput); IList ids, idTrusts, idSigs; ReadUserIDs(bcpgInput, out ids, out idTrusts, out idSigs); keys.Add(new PgpSecretKey(secret, new PgpPublicKey(secret.PublicKeyPacket, trust, keySigs, ids, idTrusts, idSigs))); // Read subkeys while (bcpgInput.NextPacketTag() == PacketTag.SecretSubkey || bcpgInput.NextPacketTag() == PacketTag.PublicSubkey) { if (bcpgInput.NextPacketTag() == PacketTag.SecretSubkey) { SecretSubkeyPacket sub = (SecretSubkeyPacket)bcpgInput.ReadPacket(); // // ignore GPG comment packets if found. // while (bcpgInput.NextPacketTag() == PacketTag.Experimental2) { bcpgInput.ReadPacket(); } TrustPacket subTrust = ReadOptionalTrustPacket(bcpgInput); IList sigList = ReadSignaturesAndTrust(bcpgInput); keys.Add(new PgpSecretKey(sub, new PgpPublicKey(sub.PublicKeyPacket, subTrust, sigList))); } else { PublicSubkeyPacket sub = (PublicSubkeyPacket)bcpgInput.ReadPacket(); TrustPacket subTrust = ReadOptionalTrustPacket(bcpgInput); IList sigList = ReadSignaturesAndTrust(bcpgInput); extraPubKeys.Add(new PgpPublicKey(sub, subTrust, sigList)); } } }
/// <summary>Extract a <c>PgpPrivateKey</c> from this secret key's encrypted contents.</summary> public PgpPrivateKey ExtractPrivateKey( char[] passPhrase) { byte[] secKeyData = secret.GetSecretKeyData(); if (secKeyData == null || secKeyData.Length < 1) { return(null); } PublicKeyPacket pubPk = secret.PublicKeyPacket; try { byte[] data = ExtractKeyData(passPhrase); BcpgInputStream bcpgIn = BcpgInputStream.Wrap(new MemoryStream(data, false)); AsymmetricKeyParameter privateKey; switch (pubPk.Algorithm) { case PublicKeyAlgorithmTag.RsaEncrypt: case PublicKeyAlgorithmTag.RsaGeneral: case PublicKeyAlgorithmTag.RsaSign: RsaPublicBcpgKey rsaPub = (RsaPublicBcpgKey)pubPk.Key; RsaSecretBcpgKey rsaPriv = new RsaSecretBcpgKey(bcpgIn); RsaPrivateCrtKeyParameters rsaPrivSpec = new RsaPrivateCrtKeyParameters( rsaPriv.Modulus, rsaPub.PublicExponent, rsaPriv.PrivateExponent, rsaPriv.PrimeP, rsaPriv.PrimeQ, rsaPriv.PrimeExponentP, rsaPriv.PrimeExponentQ, rsaPriv.CrtCoefficient); privateKey = rsaPrivSpec; break; case PublicKeyAlgorithmTag.Dsa: DsaPublicBcpgKey dsaPub = (DsaPublicBcpgKey)pubPk.Key; DsaSecretBcpgKey dsaPriv = new DsaSecretBcpgKey(bcpgIn); DsaParameters dsaParams = new DsaParameters(dsaPub.P, dsaPub.Q, dsaPub.G); privateKey = new DsaPrivateKeyParameters(dsaPriv.X, dsaParams); break; case PublicKeyAlgorithmTag.ElGamalEncrypt: case PublicKeyAlgorithmTag.ElGamalGeneral: ElGamalPublicBcpgKey elPub = (ElGamalPublicBcpgKey)pubPk.Key; ElGamalSecretBcpgKey elPriv = new ElGamalSecretBcpgKey(bcpgIn); ElGamalParameters elParams = new ElGamalParameters(elPub.P, elPub.G); privateKey = new ElGamalPrivateKeyParameters(elPriv.X, elParams); break; default: throw new PgpException("unknown public key algorithm encountered"); } return(new PgpPrivateKey(privateKey, KeyId)); } catch (PgpException e) { throw e; } catch (Exception e) { throw new PgpException("Exception constructing key", e); } }
/// <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); } }
internal PgpPrivateKey DoExtractPrivateKey(byte[] rawPassPhrase, bool clearPassPhrase) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown if (IsPrivateKeyEmpty) { return(null); } PublicKeyPacket publicKeyPacket = secret.PublicKeyPacket; try { byte[] array = ExtractKeyData(rawPassPhrase, clearPassPhrase); BcpgInputStream bcpgIn = BcpgInputStream.Wrap((Stream) new MemoryStream(array, false)); AsymmetricKeyParameter privateKey; switch (publicKeyPacket.Algorithm) { case PublicKeyAlgorithmTag.RsaGeneral: case PublicKeyAlgorithmTag.RsaEncrypt: case PublicKeyAlgorithmTag.RsaSign: { RsaPublicBcpgKey rsaPublicBcpgKey = (RsaPublicBcpgKey)publicKeyPacket.Key; RsaSecretBcpgKey rsaSecretBcpgKey = new RsaSecretBcpgKey(bcpgIn); RsaPrivateCrtKeyParameters rsaPrivateCrtKeyParameters = new RsaPrivateCrtKeyParameters(rsaSecretBcpgKey.Modulus, rsaPublicBcpgKey.PublicExponent, rsaSecretBcpgKey.PrivateExponent, rsaSecretBcpgKey.PrimeP, rsaSecretBcpgKey.PrimeQ, rsaSecretBcpgKey.PrimeExponentP, rsaSecretBcpgKey.PrimeExponentQ, rsaSecretBcpgKey.CrtCoefficient); privateKey = rsaPrivateCrtKeyParameters; break; } case PublicKeyAlgorithmTag.Dsa: { DsaPublicBcpgKey dsaPublicBcpgKey = (DsaPublicBcpgKey)publicKeyPacket.Key; DsaSecretBcpgKey dsaSecretBcpgKey = new DsaSecretBcpgKey(bcpgIn); DsaParameters parameters2 = new DsaParameters(dsaPublicBcpgKey.P, dsaPublicBcpgKey.Q, dsaPublicBcpgKey.G); privateKey = new DsaPrivateKeyParameters(dsaSecretBcpgKey.X, parameters2); break; } case PublicKeyAlgorithmTag.EC: privateKey = GetECKey("ECDH", bcpgIn); break; case PublicKeyAlgorithmTag.ECDsa: privateKey = GetECKey("ECDSA", bcpgIn); break; case PublicKeyAlgorithmTag.ElGamalEncrypt: case PublicKeyAlgorithmTag.ElGamalGeneral: { ElGamalPublicBcpgKey elGamalPublicBcpgKey = (ElGamalPublicBcpgKey)publicKeyPacket.Key; ElGamalSecretBcpgKey elGamalSecretBcpgKey = new ElGamalSecretBcpgKey(bcpgIn); ElGamalParameters parameters = new ElGamalParameters(elGamalPublicBcpgKey.P, elGamalPublicBcpgKey.G); privateKey = new ElGamalPrivateKeyParameters(elGamalSecretBcpgKey.X, parameters); break; } default: throw new PgpException("unknown public key algorithm encountered"); } return(new PgpPrivateKey(KeyId, publicKeyPacket, privateKey)); } catch (PgpException ex) { throw ex; } catch (global::System.Exception exception) { throw new PgpException("Exception constructing key", exception); } }
public Stream GetDataStream(PgpPrivateKey privKey) { byte[] array = RecoverSessionData(privKey); if (!ConfirmCheckSum(array)) { throw new PgpKeyValidationException("key checksum failed"); } SymmetricKeyAlgorithmTag symmetricKeyAlgorithmTag = (SymmetricKeyAlgorithmTag)array[0]; if (symmetricKeyAlgorithmTag == SymmetricKeyAlgorithmTag.Null) { return(encData.GetInputStream()); } string symmetricCipherName = PgpUtilities.GetSymmetricCipherName(symmetricKeyAlgorithmTag); string str = symmetricCipherName; IBufferedCipher cipher; try { str = ((!(encData is SymmetricEncIntegrityPacket)) ? (str + "/OpenPGPCFB/NoPadding") : (str + "/CFB/NoPadding")); cipher = CipherUtilities.GetCipher(str); } catch (PgpException ex) { throw ex; } catch (Exception exception) { throw new PgpException("exception creating cipher", exception); } try { KeyParameter parameters = ParameterUtilities.CreateKeyParameter(symmetricCipherName, array, 1, array.Length - 3); byte[] array2 = new byte[cipher.GetBlockSize()]; cipher.Init(forEncryption: false, new ParametersWithIV(parameters, array2)); 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, 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."); } return(encStream); } catch (PgpException ex2) { throw ex2; } catch (Exception exception2) { throw new PgpException("Exception starting decryption", exception2); } }