diff options
-rw-r--r-- | crypto/src/openpgp/PgpEncryptedDataGenerator.cs | 20 | ||||
-rw-r--r-- | crypto/src/openpgp/PgpPad.cs | 46 | ||||
-rw-r--r-- | crypto/src/openpgp/PgpPublicKey.cs | 16 | ||||
-rw-r--r-- | crypto/test/src/openpgp/examples/ClearSignedFileProcessor.cs | 2 |
4 files changed, 60 insertions, 24 deletions
diff --git a/crypto/src/openpgp/PgpEncryptedDataGenerator.cs b/crypto/src/openpgp/PgpEncryptedDataGenerator.cs index 014281b24..336baf00d 100644 --- a/crypto/src/openpgp/PgpEncryptedDataGenerator.cs +++ b/crypto/src/openpgp/PgpEncryptedDataGenerator.cs @@ -82,11 +82,13 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp : EncMethod { internal PgpPublicKey pubKey; + internal bool sessionKeyObfuscation; internal byte[][] data; - internal PubMethod(PgpPublicKey pubKey) + internal PubMethod(PgpPublicKey pubKey, bool sessionKeyObfuscation) { this.pubKey = pubKey; + this.sessionKeyObfuscation = sessionKeyObfuscation; } public override void AddSessionInfo( @@ -144,7 +146,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp IWrapper w = PgpUtilities.CreateWrapper(ecKey.SymmetricKeyAlgorithm); w.Init(true, new ParametersWithRandom(key, random)); - byte[] paddedSessionData = PgpPad.PadSessionData(sessionInfo); + byte[] paddedSessionData = PgpPad.PadSessionData(sessionInfo, sessionKeyObfuscation); byte[] C = w.Wrap(paddedSessionData, 0, paddedSessionData.Length); byte[] VB = new MPInteger(new BigInteger(1, ephPub.Q.GetEncoded(false))).GetEncoded(); @@ -317,18 +319,22 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp } /// <summary>Add a public key encrypted session key to the encrypted object.</summary> - public void AddMethod( - PgpPublicKey key) + public void AddMethod(PgpPublicKey key) { - if (!key.IsEncryptionKey) + AddMethod(key, true); + } + + public void AddMethod(PgpPublicKey key, bool sessionKeyObfuscation) + { + if (!key.IsEncryptionKey) { throw new ArgumentException("passed in key not an encryption key!"); } - methods.Add(new PubMethod(key)); + methods.Add(new PubMethod(key, sessionKeyObfuscation)); } - private void AddCheckSum( + private void AddCheckSum( byte[] sessionInfo) { Debug.Assert(sessionInfo != null); diff --git a/crypto/src/openpgp/PgpPad.cs b/crypto/src/openpgp/PgpPad.cs index 48f7f2f44..227e31019 100644 --- a/crypto/src/openpgp/PgpPad.cs +++ b/crypto/src/openpgp/PgpPad.cs @@ -11,35 +11,55 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp public static byte[] PadSessionData(byte[] sessionInfo) { - byte[] result = new byte[40]; - - Array.Copy(sessionInfo, 0, result, 0, sessionInfo.Length); + return PadSessionData(sessionInfo, true); + } - byte padValue = (byte)(result.Length - sessionInfo.Length); + public static byte[] PadSessionData(byte[] sessionInfo, bool obfuscate) + { + int length = sessionInfo.Length; + int paddedLength = ((length >> 3) + 1) << 3; - for (int i = sessionInfo.Length; i != result.Length; i++) + if (obfuscate) { - result[i] = padValue; + paddedLength = System.Math.Max(40, paddedLength); } + int padCount = paddedLength - length; + byte padByte = (byte)padCount; + + byte[] result = new byte[paddedLength]; + Array.Copy(sessionInfo, 0, result, 0, length); + for (int i = length; i < paddedLength; ++i) + { + result[i] = padByte; + } return result; } public static byte[] UnpadSessionData(byte[] encoded) { - byte padValue = encoded[encoded.Length - 1]; + int paddedLength = encoded.Length; + byte padByte = encoded[paddedLength - 1]; + int padCount = padByte; + int length = paddedLength - padCount; + int last = length - 1; - for (int i = encoded.Length - padValue; i != encoded.Length; i++) + int diff = 0; + for (int i = 0; i < paddedLength; ++i) { - if (encoded[i] != padValue) - throw new PgpException("bad padding found in session data"); + int mask = (last - i) >> 31; + diff |= (padByte ^ encoded[i]) & mask; } - byte[] taggedKey = new byte[encoded.Length - padValue]; + diff |= paddedLength & 7; + diff |= (40 - paddedLength) >> 31; - Array.Copy(encoded, 0, taggedKey, 0, taggedKey.Length); + if (diff != 0) + throw new PgpException("bad padding found in session data"); - return taggedKey; + byte[] result = new byte[length]; + Array.Copy(encoded, 0, result, 0, length); + return result; } } } diff --git a/crypto/src/openpgp/PgpPublicKey.cs b/crypto/src/openpgp/PgpPublicKey.cs index fc125e8c8..92422c413 100644 --- a/crypto/src/openpgp/PgpPublicKey.cs +++ b/crypto/src/openpgp/PgpPublicKey.cs @@ -72,7 +72,8 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp PgpSignature.PositiveCertification, PgpSignature.CasualCertification, PgpSignature.NoCertification, - PgpSignature.DefaultCertification + PgpSignature.DefaultCertification, + PgpSignature.DirectKey, }; private long keyId; @@ -369,6 +370,12 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp { return seconds; } + + seconds = GetExpirationTimeFromSig(false, PgpSignature.DirectKey); + if (seconds >= 0) + { + return seconds; + } } return 0; @@ -388,6 +395,9 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp if (hashed == null) continue; + if (!hashed.HasSubpacket(SignatureSubpacketTag.KeyExpireTime)) + continue; + long current = hashed.GetKeyExpirationTime(); if (sig.KeyId == this.KeyId) @@ -447,10 +457,10 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp } } - /// <summary>True, if this is a master key.</summary> + /// <summary>True, if this could be a master key.</summary> public bool IsMasterKey { - get { return subSigs == null; } + get { return (subSigs == null) && !(this.IsEncryptionKey && publicPk.Algorithm != PublicKeyAlgorithmTag.RsaGeneral); } } /// <summary>The algorithm code associated with the public key.</summary> diff --git a/crypto/test/src/openpgp/examples/ClearSignedFileProcessor.cs b/crypto/test/src/openpgp/examples/ClearSignedFileProcessor.cs index 8e4f7a3b5..6a12f9059 100644 --- a/crypto/test/src/openpgp/examples/ClearSignedFileProcessor.cs +++ b/crypto/test/src/openpgp/examples/ClearSignedFileProcessor.cs @@ -14,7 +14,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples * To sign a file: ClearSignedFileProcessor -s fileName secretKey passPhrase. * </p> * <p> - * To decrypt: ClearSignedFileProcessor -v fileName signatureFile publicKeyFile. + * To decrypt: ClearSignedFileProcessor -v signatureFile publicKeyFile. * </p> */ public sealed class ClearSignedFileProcessor |