From 7c958e4e6a85239d7bc6a11fa60fbc68b6312b83 Mon Sep 17 00:00:00 2001
From: Peter Dettman
Date: Thu, 30 Jul 2020 20:17:31 +0700
Subject: PGP updates from bc-java
---
crypto/src/openpgp/PgpEncryptedDataGenerator.cs | 20 ++++++----
crypto/src/openpgp/PgpPad.cs | 46 ++++++++++++++++------
crypto/src/openpgp/PgpPublicKey.cs | 16 ++++++--
.../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
}
/// Add a public key encrypted session key to the encrypted object.
- 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
}
}
- /// True, if this is a master key.
+ /// True, if this could be a master key.
public bool IsMasterKey
{
- get { return subSigs == null; }
+ get { return (subSigs == null) && !(this.IsEncryptionKey && publicPk.Algorithm != PublicKeyAlgorithmTag.RsaGeneral); }
}
/// The algorithm code associated with the public key.
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.
*
*
- * To decrypt: ClearSignedFileProcessor -v fileName signatureFile publicKeyFile.
+ * To decrypt: ClearSignedFileProcessor -v signatureFile publicKeyFile.
*
*/
public sealed class ClearSignedFileProcessor
--
cgit 1.4.1