@@ -64,6 +64,7 @@ public partial class PivSampleRun
6464 PivMainMenuItem . BuildSelfSignedCert => RunBuildSelfSignedCert ( ) ,
6565 PivMainMenuItem . BuildCert => RunBuildCert ( ) ,
6666 PivMainMenuItem . RetrieveCert => RunRetrieveCert ( ) ,
67+ PivMainMenuItem . GetMetadata => RunGetMetadata ( ) ,
6768 PivMainMenuItem . CreateAttestationStatement => RunCreateAttestationStatement ( ) ,
6869 PivMainMenuItem . GetAttestationCertificate => RunGetAttestationCert ( ) ,
6970 PivMainMenuItem . ResetPiv =>
@@ -83,6 +84,61 @@ public static bool RunUnimplementedOperation()
8384 return true ;
8485 }
8586
87+ public bool RunGetMetadata ( )
88+ {
89+ if ( _yubiKeyChosen is null )
90+ {
91+ SampleMenu . WriteMessage ( MessageType . Special , 0 , "You must choose a YubiKey first." ) ;
92+ return true ;
93+ }
94+
95+ try
96+ {
97+ using ( var pivSession = new PivSession ( _yubiKeyChosen ) )
98+ {
99+ _ = GetAsymmetricSlotNumber ( out byte slotNumber ) ;
100+ PivMetadata metadata = pivSession . GetMetadata ( slotNumber ) ;
101+
102+ if ( metadata is null )
103+ {
104+ SampleMenu . WriteMessage ( MessageType . Special , 0 , $ "\n No key or certificate found in slot { GetPivSlotName ( slotNumber ) } .\n ") ;
105+ return true ;
106+ }
107+
108+ SampleMenu . WriteMessage ( MessageType . Title , 0 , "Slot: " + GetPivSlotName ( slotNumber ) ) ;
109+ SampleMenu . WriteMessage ( MessageType . Title , 0 , "Algorithm: " + metadata . Algorithm ) ;
110+ SampleMenu . WriteMessage ( MessageType . Title , 0 , "Key status: " + metadata . KeyStatus ) ;
111+ SampleMenu . WriteMessage ( MessageType . Title , 0 , "Pin policy: " + metadata . PinPolicy ) ;
112+ SampleMenu . WriteMessage ( MessageType . Title , 0 , "Touch policy: " + metadata . TouchPolicy + "\n " ) ;
113+ }
114+ }
115+ catch ( Exception e )
116+ {
117+ SampleMenu . WriteMessage ( MessageType . Special , 0 , $ "Error getting metadata: { e . Message } ") ;
118+ }
119+
120+ return true ; // Keep the menu running
121+ }
122+ public static string GetPivSlotName ( int slotNumber )
123+ {
124+ string name = ( byte ) slotNumber switch
125+ {
126+ 0x9a => "PIV Authentication" ,
127+ 0x9c => "Digital Signature" ,
128+ 0x9d => "Key Management" ,
129+ 0x9e => "Card Authentication" ,
130+ 0xf9 => "Attestation" ,
131+
132+ // Handle the 20 "Retired" key management slots
133+ >= 0x82 and <= 0x95 => $ "Retired Key { slotNumber - 0x82 + 1 } ",
134+
135+ _ => "Unknown Slot"
136+ } ;
137+
138+ return $ "{ name } ({ ( byte ) slotNumber : X2} )";
139+ }
140+
141+
86142 public bool RunChangeRetryCount ( )
87143 {
88144 if ( ! GetNewRetryCounts ( out byte newRetryCountPin , out byte newRetryCountPuk ) )
0 commit comments