CertificateHostAlgorithm
Implements certificate support for host algorithm.
using Renci.SshNet.Security.Cryptography;
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
namespace Renci.SshNet.Security
{
[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.Nullable(0)]
public class CertificateHostAlgorithm : KeyHostAlgorithm
{
[System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1,
1,
1,
1
})]
private readonly IReadOnlyDictionary<string, Func<byte[], KeyHostAlgorithm>> _keyAlgorithms;
public Certificate Certificate { get; }
internal override SshKeyData KeyData => Certificate.KeyData;
public override byte[] Data => Certificate.Bytes;
public CertificateHostAlgorithm(string name, Key privateKey, Certificate certificate)
: base(name, privateKey)
{
Certificate = certificate;
}
public CertificateHostAlgorithm(string name, Key privateKey, Certificate certificate, DigitalSignature digitalSignature)
: base(name, privateKey, digitalSignature)
{
Certificate = certificate;
}
public CertificateHostAlgorithm(string name, Certificate certificate, IReadOnlyDictionary<string, Func<byte[], KeyHostAlgorithm>> keyAlgorithms)
: base(name, certificate.Key)
{
Certificate = certificate;
_keyAlgorithms = keyAlgorithms;
}
public CertificateHostAlgorithm(string name, Certificate certificate, DigitalSignature digitalSignature, IReadOnlyDictionary<string, Func<byte[], KeyHostAlgorithm>> keyAlgorithms)
: base(name, certificate.Key, digitalSignature)
{
Certificate = certificate;
_keyAlgorithms = keyAlgorithms;
}
public override byte[] Sign(byte[] data)
{
return new SignatureKeyData(base.Name.EndsWith("-cert-v01@openssh.com", StringComparison.Ordinal) ? base.Name.Substring(0, base.Name.Length - 21) : base.Name, base.DigitalSignature.Sign(data)).GetBytes();
}
internal override bool VerifySignatureBlob(byte[] data, byte[] signatureBlob)
{
if (!base.VerifySignatureBlob(data, signatureBlob))
return false;
ulong num = (ulong)DateTimeOffset.UtcNow.ToUnixTimeSeconds();
if (num < Certificate.ValidAfterUnixSeconds || num > Certificate.ValidBeforeUnixSeconds)
return false;
SignatureKeyData signatureKeyData = new SignatureKeyData();
signatureKeyData.Load(Certificate.Signature);
if (_keyAlgorithms == null)
throw new InvalidOperationException("Invalid usage of CertificateHostAlgorithm.VerifySignature. Use a constructor which passes key algorithms.");
if (_keyAlgorithms.TryGetValue(signatureKeyData.AlgorithmName, out Func<byte[], KeyHostAlgorithm> value))
return value(Certificate.CertificateAuthorityKey).VerifySignatureBlob(Certificate.BytesForSignature, signatureKeyData.Signature);
return false;
}
}
}