Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PIV Attestation updates #91

Merged
merged 1 commit into from
Dec 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 31 additions & 8 deletions Module/Cmdlets/Other/ConfirmYubikeyAttestion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public class ConfirmYubikeyAttestionCommand : PSCmdlet
private bool? _out_isCSPNSeries = null;
private bool? _out_AttestionMatchesCSR = null;
private PivAlgorithm? _out_Algorithm;
private string? _out_AttestionDataLocation = null;
protected override void BeginProcessing()
{
}
Expand Down Expand Up @@ -107,16 +108,38 @@ protected override void ProcessRecord()
}
else
{
extensioncsr = _CertificateRequest!.CertificateExtensions
.Cast<X509Extension>()
.FirstOrDefault(e => e.Oid!.Value == "1.3.6.1.4.1.41482.3.11");
if (extensioncsr is not null)
// If the certificateRequest contains the attestion certificate, extract it.
// Due to yubico-piv-tool not storing it in the correct place, we need to check both places.
// https://docs.yubico.com/hardware/oid/oid-piv-arc.html
if (_CertificateRequest!.CertificateExtensions.Any(e => e.Oid!.Value == "1.3.6.1.4.1.41482.3.11"))
{
_AttestionCertificate = new X509Certificate2(extensioncsr.RawData);
extensioncsr = _CertificateRequest!.CertificateExtensions
.Cast<X509Extension>()
.FirstOrDefault(e => e.Oid!.Value == "1.3.6.1.4.1.41482.3.11");
_out_AttestionDataLocation = "1.3.6.1.4.1.41482.3.11";
if (extensioncsr is not null)
{
_AttestionCertificate = new X509Certificate2(extensioncsr.RawData);
}
else
{
throw new Exception("Attestion Certificate is missing");
}
}
else
else if (_CertificateRequest!.CertificateExtensions.Any(e => e.Oid!.Value == "1.3.6.1.4.1.41482.3.1"))
{
throw new Exception("Attestion Certificate is missing");
extensioncsr = _CertificateRequest!.CertificateExtensions
.Cast<X509Extension>()
.FirstOrDefault(e => e.Oid!.Value == "1.3.6.1.4.1.41482.3.1");
_out_AttestionDataLocation = "1.3.6.1.4.1.41482.3.1";
if (extensioncsr is not null)
{
_AttestionCertificate = new X509Certificate2(extensioncsr.RawData);
}
else
{
throw new Exception("Attestion Certificate is missing");
}
}
}

Expand Down Expand Up @@ -280,7 +303,7 @@ protected override void ProcessRecord()
_out_Algorithm = PivAlgorithm.None;
}

Attestion returnObject = new Attestion(true, _out_SerialNumber, _out_FirmwareVersion, _out_PinPolicy, _out_TouchPolicy, _out_FormFactor, _out_Slot, _out_Algorithm, _out_isFIPSSeries, _out_isCSPNSeries, _out_AttestionMatchesCSR);
Attestion returnObject = new Attestion(true, _out_SerialNumber, _out_FirmwareVersion, _out_PinPolicy, _out_TouchPolicy, _out_FormFactor, _out_Slot, _out_Algorithm, _out_isFIPSSeries, _out_isCSPNSeries, AttestionMatchesCSR: _out_AttestionMatchesCSR, attestionDataLocation: _out_AttestionDataLocation);

WriteObject(returnObject);
}
Expand Down
24 changes: 17 additions & 7 deletions Module/Cmdlets/PIV/BuildYubiKeyPIVCertificateSigningRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,21 +57,31 @@ protected override void ProcessRecord()
CertificateRequest request;
X509SignatureGenerator signer;


// get the metadata catch if fails
PivMetadata? metadata = null;
PivPublicKey? publicKey = null;
try
{
publicKey = pivSession.GetMetadata(Slot).PublicKey;
if (publicKey is null)
{
throw new Exception("Public key is null");
}
metadata = pivSession.GetMetadata(Slot);
publicKey = metadata.PublicKey;

}
catch (Exception e)
{
throw new Exception($"Failed to get public key for slot {Slot}, does there exist a key?", e);
throw new Exception($"Failed to get metadata for slot {Slot}.", e);
}

if (publicKey is null)
{
throw new Exception($"Failed to get public key for slot {Slot}, does there exist a key?");
}
if (Attestation.IsPresent)
{
if (metadata.KeyStatus != PivKeyStatus.Generated)
{
throw new InvalidOperationException($"Private key must be generated on YubiKey for attested certificate requests. {Slot} is {metadata.KeyStatus}.");
}
}


using AsymmetricAlgorithm dotNetPublicKey = KeyConverter.GetDotNetFromPivPublicKey(publicKey);
Expand Down
5 changes: 4 additions & 1 deletion Module/types/Attestion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ public class Attestion
public bool? isCSPNSeries { get; } = false;
public bool? AttestionMatchesCSR { get; } = null;

public Attestion(bool attestionValidated = false, uint? serialnumber = null, FirmwareVersion? firmwareVersion = null, PivPinPolicy? pivPinPolicy = null, PivTouchPolicy? pivTouchPolicy = null, FormFactor? formFactor = null, PIVSlot? pivSlot = null, PivAlgorithm? pivAlgorithm = null, bool? isFIPSSeries = null, bool? isCSPNSeries = null, bool? AttestionMatchesCSR = null)
public string? AttestionDataLocation { get; } = null;

public Attestion(bool attestionValidated = false, uint? serialnumber = null, FirmwareVersion? firmwareVersion = null, PivPinPolicy? pivPinPolicy = null, PivTouchPolicy? pivTouchPolicy = null, FormFactor? formFactor = null, PIVSlot? pivSlot = null, PivAlgorithm? pivAlgorithm = null, bool? isFIPSSeries = null, bool? isCSPNSeries = null, bool? AttestionMatchesCSR = null, string? attestionDataLocation = null)
{
AttestionValidated = attestionValidated;
this.SerialNumber = serialnumber;
Expand All @@ -34,6 +36,7 @@ public Attestion(bool attestionValidated = false, uint? serialnumber = null, Fir
this.isFIPSSeries = isFIPSSeries;
this.isCSPNSeries = isCSPNSeries;
this.AttestionMatchesCSR = AttestionMatchesCSR;
this.AttestionDataLocation = attestionDataLocation;
}
}
}
Loading