Yo utilizo esta función que me devuelve los días que faltan hasta la caducidad y si son 60 o menos envía mensaje al usuario cada vez que entra en la app.
Código Delphi
[-]
function VerificarCaducidadCertificadoDesdePFX(const ArchivoPFX, Pwd: string; out DiasHastaCaducidad: Integer; out ErrorCode: Integer): Boolean;
var
CertStore: HCERTSTORE;
CertContext: PCERT_CONTEXT;
PFXFile: TMemoryStream;
PFXBlob: CRYPT_DATA_BLOB;
ExpFT: FILETIME;
SysTime: TSystemTime;
ExpirationDate: TDateTime;
begin
Result := False;
DiasHastaCaducidad := 0;
ErrorCode := 0;
CertStore := nil; CertContext := nil;
PFXFile := TMemoryStream.Create;
try
try
PFXFile.LoadFromFile(ArchivoPFX);
if PFXFile.Size = 0 then begin ErrorCode := 1001; Exit; end;
PFXBlob.cbData := PFXFile.Size;
GetMem(PFXBlob.pbData, PFXBlob.cbData);
try
PFXFile.Position := 0;
PFXFile.ReadBuffer(PFXBlob.pbData^, PFXBlob.cbData);
CertStore := PFXImportCertStore(PFXBlob, PWideChar(WideString(Pwd)), 0);
if CertStore = nil then begin
ErrorCode := GetLastError; Exit;
end;
CertContext := CertFindCertificateInStore(
CertStore, X509_ASN_ENCODING or PKCS_7_ASN_ENCODING,
0, CERT_FIND_ANY, nil, nil);
if CertContext = nil then begin ErrorCode := 1002; Exit; end;
ExpFT := CertContext^.pCertInfo^.NotAfter;
if not FileTimeToSystemTime(ExpFT, SysTime) then begin ErrorCode := 1003; Exit; end;
ExpirationDate := SystemTimeToDateTime(SysTime);
DiasHastaCaducidad := Trunc(ExpirationDate - Now); NotAfter := ExpirationDate;
Result := True;
finally
if Assigned(PFXBlob.pbData) then FreeMem(PFXBlob.pbData);
end;
except
on E: Exception do begin
ErrorCode := 1999; Result := False;
end;
end;
finally
if CertContext <> nil then CertFreeCertificateContext(CertContext);
if CertStore <> nil then CertCloseStore(CertStore, 0);
PFXFile.Free;
end;
end;
Tenemos la ruta del fichero de certificado p12/pfx y la contraseña del mismo.
Si el usuario utiliza un certificado instalado en el sistema tenemos la siguiente función que tambien devuelve los días hasta la caducidad:
Código Delphi
[-]
function VerificarCaducidadCertificado: Boolean;
function ExtraerCN(const SubjectName: string): string;
var
PosCN, PosFin: Integer;
begin
Result := '';
PosCN := Pos('CN=', SubjectName);
if PosCN > 0 then
begin
PosCN := PosCN + 3; PosFin := Pos(',', Copy(SubjectName, PosCN, Length(SubjectName))); if PosFin > 0 then
Result := Copy(SubjectName, PosCN, PosFin - 1)
else
Result := Copy(SubjectName, PosCN, Length(SubjectName)); end;
end;
const
CAPICOM_CURRENT_USER_STORE = 2;
CAPICOM_MY_STORE = 'My';
var
Store, Certs, Cert: OleVariant;
i: Integer;
CertName, CNExtraido: string;
begin
Result := False;
Store := CreateOleObject('CAPICOM.Store');
Store.Open(CAPICOM_CURRENT_USER_STORE, CAPICOM_MY_STORE, 0);
Certs := Store.Certificates;
if Certs.Count > 0 then
begin
for i := 1 to Certs.Count do
begin
Cert := Certs.Item[i];
CertName := Cert.SubjectName;
CNExtraido := ExtraerCN(CertName);
if CNExtraido = sVFCertificado then
begin
try
NotAfter := VarToDateTime(Cert.ValidToDate); DiasHastaCaducidad := DaysBetween(Now, NotAfter);
Result := DiasHastaCaducidad <= 60;
Exit;
except
ShowMessage('Error obteniendo la fecha de caducidad del certificado.');
Result := False;
Exit;
end;
end;
end;
end;
ShowMessage('NO SE ENCUENTRA EL CERTIFICADO EN EL ALMACÉN DE CERTIFICADOS');
end;
Compañero, espero te sirva alguna.
Un saludo,
Ramiro