Discuss this help topic in SecureBlackbox Forum
Validate XML signature
To validate XML digital signature you should perform the following steps:
To check, whether the signature contains XAdES information, you should check the value of signature handler's XAdESProcessor property. If the property is not null/nil/Nothing, then you should cast the object to TElXAdESVerifier and check if TElXAdESVerifier.IsEnabled property is true. After that, if IsEnabled property is true, you should call TElXAdESVerifier.Validate() method to validate both the XAdES signature and a signer certificate.
Otherwise, if there is no XAdES information available, you should get the signer certificate using signature handler's SignerCertificate property, and then use TElX509CertificateValidator class to validate a certificate. You can get additional (intermediate) certificates using Certificates property.
C#:
bool ValidateSignature(string sourceFilename)
{
using (TElOfficeDocument Document = new TElOfficeDocument())
{
Document.Open(sourceFilename);
if (!Document.IsSigned)
throw new Exception("Document is not signed");
bool Result = true;
for (int i = 0; i < Document.SignatureHandlerCount; i++)
{
TElOfficeCustomSignatureHandler Handler = Document.get_SignatureHandlers(i);
TElX509Certificate SignerCertificate = null;
TElCustomCertStorage AdditionalCertificates = null;
DateTime SignatureTime;
TElXAdESVerifier XAdESVerifier = null;
if (Handler is TElOfficeOpenXMLBaseSignatureHandler)
{
TElOfficeOpenXMLBaseSignatureHandler XMLSigHandler = (TElOfficeOpenXMLBaseSignatureHandler)Handler;
TSBOfficeOpenXMLSignatureValidationStatus ValidationStatus = XMLSigHandler.Validate();
Result = Result && (ValidationStatus == TSBOfficeOpenXMLSignatureValidationStatus.Valid);
SignerCertificate = XMLSigHandler.SignerCertificate;
AdditionalCertificates = XMLSigHandler.Certificates;
SignatureTime = XMLSigHandler.SignatureTime.ValueUTC;
if (XMLSigHandler.XAdESProcessor is TElXAdESVerifier)
XAdESVerifier = (TElXAdESVerifier)XMLSigHandler.XAdESProcessor;
}
else if (Handler is TElOfficeBinaryCryptoAPISignatureHandler)
{
TElOfficeBinaryCryptoAPISignatureHandler BinCryptoAPISigHandler = (TElOfficeBinaryCryptoAPISignatureHandler)Handler;
TSBOfficeBinarySignatureValidationStatus BinValidationStatus = BinCryptoAPISigHandler.Validate();
Result = Result && (BinValidationStatus == TSBOfficeBinarySignatureValidationStatus.Valid);
SignerCertificate = BinCryptoAPISigHandler.Certificate;
AdditionalCertificates = BinCryptoAPISigHandler.IntermediateCertificatesStorage;
SignatureTime = BinCryptoAPISigHandler.SignTime;
}
else if (Handler is TElOfficeBinaryXMLSignatureHandler)
{
TElOfficeBinaryXMLSignatureHandler BinXMLSigHandler = (TElOfficeBinaryXMLSignatureHandler)Handler;
TSBOfficeBinarySignatureValidationStatus BinValidationStatus = BinXMLSigHandler.Validate();
Result = Result && (BinValidationStatus == TSBOfficeBinarySignatureValidationStatus.Valid);
SignerCertificate = BinXMLSigHandler.SignerCertificate;
AdditionalCertificates = BinXMLSigHandler.Certificates;
SignatureTime = BinXMLSigHandler.SignatureTime.ValueUTC;
if (BinXMLSigHandler.XAdESProcessor is TElXAdESVerifier)
XAdESVerifier = (TElXAdESVerifier)BinXMLSigHandler.XAdESProcessor;
}
else if (Handler is TElOpenOfficeSignatureHandler)
{
TElOpenOfficeSignatureHandler ODFSigHandler = (TElOpenOfficeSignatureHandler)Handler;
TSBOpenOfficeSignatureValidationStatus ODFValidationStatus = ODFSigHandler.Validate();
Result = Result && (ODFValidationStatus == TSBOpenOfficeSignatureValidationStatus.Valid);
SignerCertificate = ODFSigHandler.SignerCertificate;
AdditionalCertificates = ODFSigHandler.Certificates;
SignatureTime = ODFSigHandler.SignatureTime.ValueUTC;
if (ODFSigHandler.XAdESProcessor is TElXAdESVerifier)
XAdESVerifier = (TElXAdESVerifier)ODFSigHandler.XAdESProcessor;
}
else if ((Handler is TElOfficeBinaryUnsupportedSignatureHandler) ||
(Handler is TElOfficeOpenXMLUnsupportedSignatureHandler) ||
(Handler is TElOpenOfficeUnsupportedSignatureHandler))
throw new Exception("Unsupported signature handler");
else if (Handler is TElOfficeBinaryInvalidSignatureHandler)
throw new Exception("Invalid signature handler: " + ((TElOfficeBinaryInvalidSignatureHandler)Handler).ErrorMessage);
else if (Handler is TElOfficeOpenXMLInvalidSignatureHandler)
throw new Exception("Invalid signature handler: " + ((TElOfficeOpenXMLInvalidSignatureHandler)Handler).ErrorMessage);
else if (Handler is TElOpenOfficeInvalidSignatureHandler)
throw new Exception("Invalid signature handler: " + ((TElOpenOfficeInvalidSignatureHandler)Handler).ErrorMessage);
else
throw new Exception("Unknown signature handler");
if ((XAdESVerifier != null) && XAdESVerifier.IsEnabled)
{
// call XAdESVerifier.Validate() method to validate XAdES info
}
else
{
// use TElX509CertificateValidator class to validate the signer certificate
}
}
return Result;
}
}
Delphi:
function ValidateSignature(const SourceFilename : string) : Boolean;
var
Document : TElOfficeDocument;
Handler : TElOfficeCustomSignatureHandler;
XMLSigHandler : TElOfficeOpenXMLBaseSignatureHandler;
ODFSigHandler : TElOpenOfficeSignatureHandler;
BinXMLSigHandler : TElOfficeBinaryXMLSignatureHandler;
BinCryptoAPISigHandler : TElOfficeBinaryCryptoAPISignatureHandler;
ValidationStatus : TSBOfficeOpenXMLSignatureValidationStatus;
BinValidationStatus : TSBOfficeBinarySignatureValidationStatus;
ODFValidationStatus : TSBOpenOfficeSignatureValidationStatus;
SignerCertificate : TElX509Certificate;
AdditionalCertificates : TElCustomCertStorage;
SignatureTime : TDateTime;
XAdESVerifier : TElXAdESVerifier;
i : Integer;
begin
Document := TElOfficeDocument.Create(nil);
try
Document.Open(SourceFilename);
if not Document.IsSigned then
raise Exception.Create('Document is not signed');
Result := true;
for i := 0 to Document.SignatureHandlerCount - 1 do
begin
Handler := Document.SignatureHandlers[i];
XAdESVerifier := nil;
if Handler is TElOfficeOpenXMLBaseSignatureHandler then
begin
XMLSigHandler := TElOfficeOpenXMLBaseSignatureHandler(Handler);
ValidationStatus := XMLSigHandler.Validate();
Result := Result and (ValidationStatus = svsValid);
SignerCertificate := XMLSigHandler.SignerCertificate;
AdditionalCertificates := XMLSigHandler.Certificates;
SignatureTime := XMLSigHandler.SignatureTime.ValueUTC;
if XMLSigHandler.XAdESProcessor is TElXAdESVerifier then
XAdESVerifier := TElXAdESVerifier(XMLSigHandler.XAdESProcessor);
end
else
if Handler is TElOfficeBinaryCryptoAPISignatureHandler then
begin
BinCryptoAPISigHandler := TElOfficeBinaryCryptoAPISignatureHandler(Handler);
BinValidationStatus := BinCryptoAPISigHandler.Validate();
Result := Result and (BinValidationStatus = bsvsValid);
SignerCertificate := BinCryptoAPISigHandler.Certificate;
AdditionalCertificates := BinCryptoAPISigHandler.IntermediateCertificatesStorage;
SignatureTime := BinCryptoAPISigHandler.SignTime;
end
else
if Handler is TElOfficeBinaryXMLSignatureHandler then
begin
BinXMLSigHandler := TElOfficeBinaryXMLSignatureHandler(Handler);
BinValidationStatus := BinXMLSigHandler.Validate();
Result := Result and (BinValidationStatus = bsvsValid);
SignerCertificate := BinXMLSigHandler.SignerCertificate;
AdditionalCertificates := BinXMLSigHandler.Certificates;
SignatureTime := BinXMLSigHandler.SignatureTime.ValueUTC;
if BinXMLSigHandler.XAdESProcessor is TElXAdESVerifier then
XAdESVerifier := TElXAdESVerifier(BinXMLSigHandler.XAdESProcessor);
end
else
if Handler is TElOpenOfficeSignatureHandler then
begin
ODFSigHandler := TElOpenOfficeSignatureHandler(Handler);
ODFValidationStatus := ODFSigHandler.Validate();
Result := Result and (ODFValidationStatus = osvsValid);
SignerCertificate := ODFSigHandler.SignerCertificate;
AdditionalCertificates := ODFSigHandler.Certificates;
SignatureTime := ODFSigHandler.SignatureTime.ValueUTC;
if ODFSigHandler.XAdESProcessor is TElXAdESVerifier then
XAdESVerifier := TElXAdESVerifier(ODFSigHandler.XAdESProcessor);
end
else
if (Handler is TElOfficeBinaryUnsupportedSignatureHandler) or
(Handler is TElOfficeOpenXMLUnsupportedSignatureHandler) or
(Handler is TElOpenOfficeUnsupportedSignatureHandler) then
raise Exception.Create('Unsupported signature handler')
else
if Handler is TElOfficeBinaryInvalidSignatureHandler then
raise Exception.Create('Invalid signature handler: ' + TElOfficeBinaryInvalidSignatureHandler(Handler).ErrorMessage)
else
if Handler is TElOfficeOpenXMLInvalidSignatureHandler then
raise Exception.Create('Invalid signature handler: ' + TElOfficeOpenXMLInvalidSignatureHandler(Handler).ErrorMessage)
else
if Handler is TElOpenOfficeInvalidSignatureHandler then
raise Exception.Create('Invalid signature handler: ' + TElOpenOfficeInvalidSignatureHandler(Handler).ErrorMessage)
else
raise Exception.Create('Unknown signature handler');
if Assigned(XAdESVerifier) and XAdESVerifier.IsEnabled then
begin
// call XAdESVerifier.Validate() method to validate XAdES info
end
else
begin
// use TElX509CertificateValidator class to validate the signer certificate
end;
end;
finally
FreeAndNil(Document);
end;
end;