2using System.Globalization;
22 private static readonly MGF1 defaultMaskGenerationFunction =
new(defaultHashFunction);
26 private int saltLength = 20;
27 private int trailerField = 1;
28 private bool configured =
false;
33 public override string Oid =>
"1.2.840.113549.1.1.10";
47 if (SecurityInfo.Length < 2 ||
48 SecurityInfo[1] is not Vector RsaSsaPssParameters)
53 int c = RsaSsaPssParameters.Length;
57 if (RsaSsaPssParameters.FirstElement is not Vector HashVector ||
58 HashVector.Length < 1)
65 if (HashVector.FirstElement is Vector v &&
79 if (RsaSsaPssParameters[1] is not Vector MaskGenerationFunctionVector ||
80 MaskGenerationFunctionVector.Length < 1 ||
91 if (RsaSsaPssParameters[2] is not Vector SaltLengthVector ||
92 SaltLengthVector.Length < 1 ||
93 SaltLengthVector.FirstElement is not BigInteger SaltLength ||
94 SaltLength <
int.MinValue ||
95 SaltLength >
int.MaxValue)
100 this.saltLength = (int)SaltLength;
104 if (RsaSsaPssParameters[3] is not Vector TrailerFieldVector ||
105 TrailerFieldVector.Length < 1 ||
106 TrailerFieldVector.FirstElement is not BigInteger TrailerField ||
107 TrailerField <
int.MinValue ||
108 TrailerField >
int.MaxValue)
113 this.trailerField = (int)TrailerField;
121 this.configured =
true;
149 Client?.
Error(
"Unable to get RSA public key from certificate.");
159 return Verify(this.hashFunction, this.maskGenerationFunction,
183 StringBuilder? Msg = HasSniffer ?
new StringBuilder() :
null;
187 Msg!.AppendLine(
"RSS-PSS signature verification parameters:");
188 Msg.Append(
"n (Modulus, dec): ");
189 Msg.AppendLine(n.ToString(CultureInfo.InvariantCulture));
190 Msg.Append(
"e (Exponent, dec): ");
191 Msg.AppendLine(e.ToString(CultureInfo.InvariantCulture));
192 Msg.Append(
"S (Signature, dec): ");
193 Msg.AppendLine(S.ToString(CultureInfo.InvariantCulture));
194 Msg.Append(
"Salt length (dec): ");
195 Msg.AppendLine(SaltLen.ToString(CultureInfo.InvariantCulture));
196 Msg.Append(
"Hash function: ");
198 Msg.Append(
"MGF function: ");
199 Msg.AppendLine(Mgf.ToString());
200 Msg.Append(
"Message (hex): ");
213 byte[] EMBin = EM.ToByteArray(
true,
true);
214 int EMLen = (int)(n.GetBitLength() + 7) / 8;
216 if (EMBin.Length < EMLen)
218 byte[] EMBin2 =
new byte[EMLen];
219 Buffer.BlockCopy(EMBin, 0, EMBin2, EMLen - EMBin.Length, EMBin.Length);
225 Msg!.Append(
"EM = S^e (hex): ");
229 if (EMBin[^1] != 0xbc)
234 Client.
Error(
"S^e does not end with BC. Invalid signature.");
241 int MaskedDBLen = EMBin.Length - 1 - HLen;
242 byte[] MaskedDB =
new byte[MaskedDBLen];
243 byte[] HashDigest =
new byte[HLen];
245 Buffer.BlockCopy(EMBin, 0, MaskedDB, 0, MaskedDBLen);
246 Buffer.BlockCopy(EMBin, MaskedDBLen, HashDigest, 0, HLen);
250 Msg!.Append(
"Masked DB (hex): ");
252 Msg!.Append(
"Hash Digest 1 (hex): ");
260 Msg!.Append(
"DB Mask (hex): ");
264 byte[] DB = TravelDocumentsClient.XOR(MaskedDB, DBMask);
270 Msg!.Append(
"DB (hex): ");
277 while (i < c && DB[i] == 0)
287 Client.
Error(
"DB invalid. Invalid signature.");
294 byte[] H2 =
new byte[8 + HLen + SaltLen];
296 Buffer.BlockCopy(Digest, 0, H2, 8, HLen);
297 Buffer.BlockCopy(DB, i, H2, 8 + HLen, SaltLen);
303 Msg!.Append(
"Hash Digest 2 (hex): ");
307 for (i = 0; i < HLen; i++)
309 if (Digest[i] != HashDigest[i])
314 Client.
Error(
"Hash digests do not match. Invalid signature.");
Static class for parsing and decoding security objects encoded using Abstract Syntax Notation 1 (ASN....
static int ReportAlgorithmUse(string Name)
Records an Elliptic Curve has been used.
Abstract base class for hash functions.
abstract int HashLength
Number of bytes used for the hash digest.
abstract byte[] ComputeHash(byte[] Data)
Computes a Hash Digest from binary data.
override string ToString()
Abstract base class of Mask Generation Functions.
abstract byte[] CalculateMask(byte[] Seed, int Length)
Calcaultes a mask of a specific length, given a seed.
Abstract base class for public keys.
The RSA Public Key object does not have an OID of its own. Instead, it uses the OID of rsaEncryption ...
BigInteger Exponent
Exponent
BigInteger Modulus
Modulus
abstract string Oid
OID identifying the type of object.
RSASSA-PSS algorithm, as defined in RFCs 3447, 4055 and 4056: https://www.rfc-editor....
override bool IsConfigured
If the object has been configured.
override string Oid
OID identifying the type of object.
static bool Verify(HashFunction H, MaskGenerationFunction Mgf, BigInteger n, BigInteger e, byte[] Message, BigInteger S, int SaltLen, ICommunicationLayer? Client)
Verifies an RSA-PSS signature.
override Waher.Security.HashFunctionArray HashAlgorithm
Hash algorithm to use.
override bool VerifySignature(byte[] Data, byte[] Signature, IPublicKey PublicKey, ICommunicationLayer? Client)
Verifies a digital signature.
override string HashAlgorithmOid
OID of Hash algorithm to use.
override bool Configure(Vector SecurityInfo)
If the object can be configured by the security information provided.
override string ToString()
Abstract base class for elliptic curves.
static BigInteger ToInt(byte[] Binary, bool BigEndian)
Converts a little-endian binary representation of a big integer to a BigInteger.
Integer arithmetic, modulus a prime.
BigInteger Multiply(BigInteger a, BigInteger b)
Multiplies two numbers, modulus p
Contains methods for simple hash calculations.
static string BinaryToString(byte[] Data)
Converts an array of bytes to a string with their hexadecimal representations (in lower case).
Interface for public keys.
void Information(string Comment)
Called to inform the viewer of something.
void Error(string Error)
Called to inform the viewer of an error state.
Interface for observable classes implementing communication protocols.
bool HasSniffers
If there are sniffers registered on the object.