-
Notifications
You must be signed in to change notification settings - Fork 464
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added base class CertificateAlgorithm (#432)
* Added base class CertificateAlgorithm * Bumped version to 10.0.0-beta6
- Loading branch information
1 parent
95b5631
commit b387094
Showing
4 changed files
with
158 additions
and
157 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
using System; | ||
using System.Security.Cryptography; | ||
using System.Security.Cryptography.X509Certificates; | ||
|
||
namespace JWT.Algorithms | ||
{ | ||
public abstract class CertificateAlgorithm<T> : IAsymmetricAlgorithm | ||
where T : class | ||
{ | ||
protected readonly T _publicKey; | ||
protected readonly T _privateKey; | ||
|
||
protected CertificateAlgorithm(T publicKey, T privateKey) | ||
{ | ||
_publicKey = publicKey ?? throw new ArgumentNullException(nameof(publicKey)); | ||
_privateKey = privateKey ?? throw new ArgumentNullException(nameof(privateKey)); | ||
} | ||
|
||
protected CertificateAlgorithm(T publicKey) | ||
{ | ||
_publicKey = publicKey ?? throw new ArgumentNullException(nameof(publicKey)); | ||
_privateKey = null; | ||
} | ||
|
||
protected CertificateAlgorithm(X509Certificate2 cert) | ||
{ | ||
if (cert is null) | ||
throw new InvalidOperationException(nameof(cert)); | ||
|
||
_publicKey = GetPublicKey(cert) ?? throw new Exception("Certificate must have public key."); | ||
_privateKey = GetPrivateKey(cert); | ||
} | ||
|
||
/// <inheritdoc /> | ||
public abstract string Name { get; } | ||
|
||
/// <inheritdoc /> | ||
public abstract HashAlgorithmName HashAlgorithmName { get; } | ||
|
||
/// <inheritdoc /> | ||
public byte[] Sign(byte[] key, byte[] bytesToSign) => | ||
Sign(bytesToSign); | ||
|
||
/// <summary> | ||
/// Signs the provided byte array with the private key. | ||
/// </summary> | ||
public byte[] Sign(byte[] bytesToSign) | ||
{ | ||
if (bytesToSign is null) | ||
throw new ArgumentNullException(nameof(bytesToSign)); | ||
if (_privateKey is null) | ||
throw new InvalidOperationException("Can't sign data without private key"); | ||
|
||
return SignData(bytesToSign); | ||
} | ||
|
||
/// <inheritdoc /> | ||
public bool Verify(byte[] bytesToSign, byte[] signature) | ||
{ | ||
if (bytesToSign is null) | ||
throw new ArgumentNullException(nameof(bytesToSign)); | ||
if (signature is null) | ||
throw new ArgumentNullException(nameof(signature)); | ||
|
||
return VerifyData(bytesToSign, signature); | ||
} | ||
|
||
protected abstract T GetPublicKey(X509Certificate2 cert); | ||
|
||
protected abstract T GetPrivateKey(X509Certificate2 cert); | ||
|
||
protected abstract byte[] SignData(byte[] bytesToSign); | ||
|
||
protected abstract bool VerifyData(byte[] bytesToSign, byte[] signature); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,94 +1,57 @@ | ||
#if NETSTANDARD2_0 || NET6_0 | ||
using System; | ||
using System.Security.Cryptography; | ||
using System.Security.Cryptography.X509Certificates; | ||
|
||
namespace JWT.Algorithms | ||
{ | ||
/// <summary> | ||
/// Abstract base class for all ECDSA algorithms | ||
/// </summary> | ||
public abstract class ECDSAAlgorithm : IAsymmetricAlgorithm | ||
{ | ||
private readonly ECDsa _publicKey; | ||
private readonly ECDsa _privateKey; | ||
|
||
/// <summary> | ||
/// Creates an instance of <see cref="ECDSAAlgorithm" /> using the provided pair of public and private keys. | ||
/// </summary> | ||
/// <param name="publicKey">The public key for verifying the data.</param> | ||
/// <param name="privateKey">The private key for signing the data.</param> | ||
protected ECDSAAlgorithm(ECDsa publicKey, ECDsa privateKey) | ||
{ | ||
_publicKey = publicKey ?? throw new ArgumentNullException(nameof(publicKey)); | ||
_privateKey = privateKey ?? throw new ArgumentNullException(nameof(privateKey)); | ||
} | ||
|
||
/// <summary> | ||
/// Creates an instance of <see cref="ECDSAAlgorithm" /> using the provided public key only. | ||
/// </summary> | ||
/// <remarks> | ||
/// An instance created using this constructor can only be used for verifying the data, not for signing it. | ||
/// </remarks> | ||
/// <param name="publicKey">The public key for verifying the data.</param> | ||
protected ECDSAAlgorithm(ECDsa publicKey) | ||
{ | ||
_publicKey = publicKey ?? throw new ArgumentNullException(nameof(publicKey)); | ||
_privateKey = null; | ||
} | ||
|
||
/// <summary> | ||
/// Creates an instance using the provided certificate. | ||
/// </summary> | ||
/// <param name="cert">The certificate having a public key and an optional private key.</param> | ||
protected ECDSAAlgorithm(X509Certificate2 cert) | ||
{ | ||
_publicKey = GetPublicKey(cert) ?? throw new Exception("Certificate's PublicKey cannot be null."); | ||
_privateKey = GetPrivateKey(cert); | ||
} | ||
|
||
/// <inheritdoc /> | ||
public abstract string Name { get; } | ||
|
||
/// <inheritdoc /> | ||
public abstract HashAlgorithmName HashAlgorithmName { get; } | ||
|
||
/// <inheritdoc /> | ||
public byte[] Sign(byte[] key, byte[] bytesToSign) | ||
{ | ||
if (_privateKey is null) | ||
throw new InvalidOperationException("Can't sign data without private key"); | ||
|
||
return Sign(bytesToSign); | ||
} | ||
|
||
/// <summary> | ||
/// Signs the provided bytes. | ||
/// </summary> | ||
/// <param name="bytesToSign">The bytes to sign.</param> | ||
/// <returns>The signed bytes.</returns> | ||
public byte[] Sign(byte[] bytesToSign) | ||
=> _privateKey.SignData(bytesToSign, this.HashAlgorithmName); | ||
|
||
/// <inheritdoc /> | ||
public bool Verify(byte[] bytesToSign, byte[] signature) | ||
=> _publicKey.VerifyData(bytesToSign, signature, this.HashAlgorithmName); | ||
|
||
private static ECDsa GetPrivateKey(X509Certificate2 cert) | ||
{ | ||
if (cert is null) | ||
throw new ArgumentNullException(nameof(cert)); | ||
|
||
return cert.GetECDsaPrivateKey(); | ||
} | ||
|
||
private static ECDsa GetPublicKey(X509Certificate2 cert) | ||
{ | ||
if (cert is null) | ||
throw new ArgumentNullException(nameof(cert)); | ||
|
||
return cert.GetECDsaPublicKey(); | ||
} | ||
} | ||
} | ||
#endif | ||
#if NETSTANDARD2_0 || NET6_0 | ||
using System.Security.Cryptography; | ||
using System.Security.Cryptography.X509Certificates; | ||
|
||
namespace JWT.Algorithms | ||
{ | ||
/// <summary> | ||
/// Abstract base class for all ECDSA algorithms | ||
/// </summary> | ||
public abstract class ECDSAAlgorithm : CertificateAlgorithm<ECDsa> | ||
{ | ||
/// <summary> | ||
/// Creates an instance of <see cref="ECDSAAlgorithm" /> using the provided pair of public and private keys. | ||
/// </summary> | ||
/// <param name="publicKey">The public key for verifying the data.</param> | ||
/// <param name="privateKey">The private key for signing the data.</param> | ||
protected ECDSAAlgorithm(ECDsa publicKey, ECDsa privateKey) | ||
: base(publicKey, privateKey) | ||
{ | ||
} | ||
|
||
/// <summary> | ||
/// Creates an instance of <see cref="ECDSAAlgorithm" /> using the provided public key only. | ||
/// </summary> | ||
/// <remarks> | ||
/// An instance created using this constructor can only be used for verifying the data, not for signing it. | ||
/// </remarks> | ||
/// <param name="publicKey">The public key for verifying the data.</param> | ||
protected ECDSAAlgorithm(ECDsa publicKey) | ||
: base(publicKey) | ||
{ | ||
} | ||
|
||
/// <summary> | ||
/// Creates an instance using the provided certificate. | ||
/// </summary> | ||
/// <param name="cert">The certificate having a public key and an optional private key.</param> | ||
protected ECDSAAlgorithm(X509Certificate2 cert) | ||
: base(cert) | ||
{ | ||
} | ||
|
||
protected override ECDsa GetPublicKey(X509Certificate2 cert) => | ||
cert.GetECDsaPublicKey(); | ||
|
||
protected override ECDsa GetPrivateKey(X509Certificate2 cert) => | ||
cert.GetECDsaPrivateKey(); | ||
|
||
|
||
protected override byte[] SignData(byte[] bytesToSign) => | ||
_privateKey.SignData(bytesToSign, this.HashAlgorithmName); | ||
|
||
protected override bool VerifyData(byte[] bytesToSign, byte[] signature) => | ||
_publicKey.VerifyData(bytesToSign, signature, this.HashAlgorithmName); | ||
} | ||
} | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters