using System;
using System.IO;
namespace Org.BouncyCastle.Tls
{
/// RFC 5246 7.4.1.4.1
public sealed class SignatureAndHashAlgorithm
{
public static readonly SignatureAndHashAlgorithm ecdsa_brainpoolP256r1tls13_sha256 =
Create(SignatureScheme.ecdsa_brainpoolP256r1tls13_sha256);
public static readonly SignatureAndHashAlgorithm ecdsa_brainpoolP384r1tls13_sha384 =
Create(SignatureScheme.ecdsa_brainpoolP384r1tls13_sha384);
public static readonly SignatureAndHashAlgorithm ecdsa_brainpoolP512r1tls13_sha512 =
Create(SignatureScheme.ecdsa_brainpoolP512r1tls13_sha512);
public static readonly SignatureAndHashAlgorithm ed25519 =
Create(SignatureScheme.ed25519);
public static readonly SignatureAndHashAlgorithm ed448 =
Create(SignatureScheme.ed448);
public static readonly SignatureAndHashAlgorithm gostr34102012_256 =
Create(HashAlgorithm.Intrinsic, SignatureAlgorithm.gostr34102012_256);
public static readonly SignatureAndHashAlgorithm gostr34102012_512 =
Create(HashAlgorithm.Intrinsic, SignatureAlgorithm.gostr34102012_512);
public static readonly SignatureAndHashAlgorithm rsa_pss_rsae_sha256 =
Create(SignatureScheme.rsa_pss_rsae_sha256);
public static readonly SignatureAndHashAlgorithm rsa_pss_rsae_sha384 =
Create(SignatureScheme.rsa_pss_rsae_sha384);
public static readonly SignatureAndHashAlgorithm rsa_pss_rsae_sha512 =
Create(SignatureScheme.rsa_pss_rsae_sha512);
public static readonly SignatureAndHashAlgorithm rsa_pss_pss_sha256 =
Create(SignatureScheme.rsa_pss_pss_sha256);
public static readonly SignatureAndHashAlgorithm rsa_pss_pss_sha384 =
Create(SignatureScheme.rsa_pss_pss_sha384);
public static readonly SignatureAndHashAlgorithm rsa_pss_pss_sha512 =
Create(SignatureScheme.rsa_pss_pss_sha512);
public static SignatureAndHashAlgorithm GetInstance(short hashAlgorithm, short signatureAlgorithm)
{
switch (hashAlgorithm)
{
case HashAlgorithm.Intrinsic:
return GetInstanceIntrinsic(signatureAlgorithm);
default:
return Create(hashAlgorithm, signatureAlgorithm);
}
}
private static SignatureAndHashAlgorithm GetInstanceIntrinsic(short signatureAlgorithm)
{
switch (signatureAlgorithm)
{
case SignatureAlgorithm.ed25519:
return ed25519;
case SignatureAlgorithm.ed448:
return ed448;
case SignatureAlgorithm.gostr34102012_256:
return gostr34102012_256;
case SignatureAlgorithm.gostr34102012_512:
return gostr34102012_512;
case SignatureAlgorithm.rsa_pss_rsae_sha256:
return rsa_pss_rsae_sha256;
case SignatureAlgorithm.rsa_pss_rsae_sha384:
return rsa_pss_rsae_sha384;
case SignatureAlgorithm.rsa_pss_rsae_sha512:
return rsa_pss_rsae_sha512;
case SignatureAlgorithm.rsa_pss_pss_sha256:
return rsa_pss_pss_sha256;
case SignatureAlgorithm.rsa_pss_pss_sha384:
return rsa_pss_pss_sha384;
case SignatureAlgorithm.rsa_pss_pss_sha512:
return rsa_pss_pss_sha512;
case SignatureAlgorithm.ecdsa_brainpoolP256r1tls13_sha256:
return ecdsa_brainpoolP256r1tls13_sha256;
case SignatureAlgorithm.ecdsa_brainpoolP384r1tls13_sha384:
return ecdsa_brainpoolP384r1tls13_sha384;
case SignatureAlgorithm.ecdsa_brainpoolP512r1tls13_sha512:
return ecdsa_brainpoolP512r1tls13_sha512;
default:
return Create(HashAlgorithm.Intrinsic, signatureAlgorithm);
}
}
private static SignatureAndHashAlgorithm Create(int signatureScheme)
{
short hashAlgorithm = SignatureScheme.GetHashAlgorithm(signatureScheme);
short signatureAlgorithm = SignatureScheme.GetSignatureAlgorithm(signatureScheme);
return Create(hashAlgorithm, signatureAlgorithm);
}
private static SignatureAndHashAlgorithm Create(short hashAlgorithm, short signatureAlgorithm)
{
return new SignatureAndHashAlgorithm(hashAlgorithm, signatureAlgorithm);
}
private readonly short m_hash;
private readonly short m_signature;
///
///
public SignatureAndHashAlgorithm(short hash, short signature)
{
/*
* TODO]tls] The TlsUtils methods are inlined here to avoid circular static initialization
* b/w these classes. We should refactor parts of TlsUtils into separate classes. e.g. the
* TLS low-level encoding methods, and/or the SigAndHash registry and methods.
*/
//if (!TlsUtilities.IsValidUint8(hash))
if ((hash & 0xFF) != hash)
throw new ArgumentException("should be a uint8", "hash");
//if (!TlsUtilities.IsValidUint8(signature))
if ((signature & 0xFF) != signature)
throw new ArgumentException("should be a uint8", "signature");
this.m_hash = hash;
this.m_signature = signature;
}
///
public short Hash
{
get { return m_hash; }
}
///
public short Signature
{
get { return m_signature; }
}
/// Encode this to a .
/// the to encode to.
///
public void Encode(Stream output)
{
TlsUtilities.WriteUint8(Hash, output);
TlsUtilities.WriteUint8(Signature, output);
}
/// Parse a from a .
/// the to parse from.
/// a object.
///
public static SignatureAndHashAlgorithm Parse(Stream input)
{
short hash = TlsUtilities.ReadUint8(input);
short signature = TlsUtilities.ReadUint8(input);
return GetInstance(hash, signature);
}
public override bool Equals(object obj)
{
if (!(obj is SignatureAndHashAlgorithm))
return false;
SignatureAndHashAlgorithm other = (SignatureAndHashAlgorithm)obj;
return other.Hash == Hash && other.Signature == Signature;
}
public override int GetHashCode()
{
return ((int)Hash << 16) | (int)Signature;
}
public override string ToString()
{
return "{" + HashAlgorithm.GetText(Hash) + "," + SignatureAlgorithm.GetText(Signature) + "}";
}
}
}