For a quick explanation and code examples of validating XML signatures,
see the following quick start articles on the Adobe Developer Connection:
Adobe® AIR® provides the XMLSignatureValidator class and IURIDereferencer interface
for validating XML signatures. The XML syntax accepted by the XMLSignatureValidator
class is a subset of the W3C recommendation for XML Signature Syntax
and Processing. (Because only a subset of the recommendation is supported,
not all legal signatures can be validated.) AIR does not provide
an API for creating XML signatures.
XML signature validation classes
The
XML signature validation API includes the following classes:
Package
|
Classes
|
flash.security
|
XMLSignatureValidator
string constants are defined in the following classes:
|
flash.events
|
|
Using the XML signature validation classes
To use the XMLSignatureValidator class to validate an XML signature,
you must:
-
Create an XMLSignatureValidator object
-
Provide an implementation of the IURIDereferencer interface.
The XMLSignatureValidator object calls the IURIDereferencer
dereference()
method, passing
in the URI for each reference in a signature. The
dereference()
method
must resolve the URI and return the referenced data (which could
be in the same document as the signature, or could be in an external
resource).
-
Set the certificate trust, revocation checking, and reference
validation settings of the XMLSignatureValidator object as appropriate
for your application.
-
Add event listeners for the
complete
and
error
events.
-
Call the
verify()
method, passing in the
signature to validate.
-
Handle the
complete
and
error
events
and interpret the results.
The following example implements a
validate()
function
that verifies the validity of an XML signature. The XMLSignatureValidator
properties are set such that the signing certificate must be in
the system trust store, or chain to a certificate in the trust store.
The example also assumes that a suitable IURIDereferencer class
named
XMLDereferencer
exists.
private function validate( xmlSignature:XML ):void
{
var verifier:XMLSignatureValidator = new XMLSignatureValidator();
verifier.addEventListener(Event.COMPLETE, verificationComplete);
verifier.addEventListener(ErrorEvent.ERROR, verificationError);
try
{
verifier.uriDereferencer = new XMLDereferencer();
verifier.referencesValidationSetting =
ReferencesValidationSetting.VALID_IDENTITY;
verifier.revocationCheckSetting = RevocationCheckSettings.BEST_EFFORT;
verifier.useSystemTrustStore = true;
//Verify the signature
verifier.verify( xmlSignature );
}
catch (e:Error)
{
trace("Verification error.\n" + e);
}
}
//Trace verification results
private function verificationComplete(event:Event):void
var signature:XMLSignatureValidator = event.target as XMLSignatureValidator;
trace("Signature status: " + signature.validityStatus + "\n");
trace(" Digest status: " + signature.digestStatus + "\n");
trace(" Identity status: " + signature.identityStatus + "\n");
trace(" Reference status: " + signature.referencesStatus + "\n");
}
private function verificationError(event:ErrorEvent):void
{
trace("Verification error.\n" + event.text);
}
The XML signature validation process
When you call the XMLSignatureValidator
verify()
method,
AIR performs the following steps:
-
The runtime verifies the cryptographic integrity of the
signature using the public key of the signing certificate.
-
The runtime establishes the cryptographic integrity, identity,
and trustworthiness of the certificate based on the current settings
of the XMLSignatureValidator object.
The trust placed in
the signing certificate is key to the integrity of the validation
process. Signature validation is conducted using a well-defined cryptographic
process, but the trustworthiness of the signing certificate is a judgment
that cannot be made algorithmically.
In general, you have
three ways to decide whether a certificate is trustworthy:
-
By relying on certification authorities and the operating
system trust store.
-
By obtaining, directly from the signer, a copy of the certificate,
another certificate that serves as a trust anchor for the certificate,
or sufficient information to reliably identify the certificate,
such as the public key.
-
Asking the end user of your application if they trust the
certificate. Such a query is invalid with self-signed certificates
since the identifying information in the certificate is inherently
unreliable.
-
The runtime verifies the cryptographic integrity of the signed
data.
The signed data is verified with the help of your IURIDereferencer
implementation. For each reference in the signature document, the
IURIDereferencer implementation
dereference()
method
is called. The data returned by the
dereference()
method
is used to compute the reference digest. This digest value is compared
to the digest recorded in the signature document. If the digests
match, then the data has not been altered since it was signed.
One
important consideration when relying on the results of validating
an XML signature is that only what is signed is secure. For example,
consider a signed manifest listing the files in a package. When
the XMLSignatureValidator verifies the signature, it only checks
whether the manifest itself is unaltered. The data in the files
is not signed, so the signature will still validate when files referenced
in the manifest are changed or deleted.
Note:
To verify files
in such a manifest, you can compute the digest of the file data (using
the same hashing algorithm used in the manifest) and compare the
result to the digest stored in the signed manifest. In some cases,
you should also check for the presence of additional files.
Interpreting validation results
The validation results are reported by the status properties
of the XMLSignatureValidator object. These properties can be read
after the validator object dispatches the
complete
event.
The four status properties include:
validityStatus
,
digestStatus
,
identityStatus
,
and
referencesStatus
.
The validityStatus property
The
validityStatus
property reports the overall
validity of the signature. The
validityStatus
depends
on the state of the other three status properties and can have one
of the following values:
-
valid
— If
digestStatus
,
identityStatus
,
and
referencesStatus
are all
valid
.
-
invalid
— If one or more of the individual
status properties is
invalid
.
-
unknown
— If one or more of the individual
status properties is
unknown
and no individual
status is
invalid
.
The digestStatus property
The
digestStatus
property reports the results
of the cryptographic verification of the message digest. The
digestStatus
property
can have one of the following values:
-
valid
— If the signature document itself
is unaltered since signing.
-
invalid
— If the signature document has
been altered or is malformed.
-
unknown
— If the
verify()
method
has not completed without error.
The identityStatus property
The
identityStatus
property reports the status
of the signing certificate. The value of this property depends on
several factors including:
-
the cryptographic integrity of the certificate
-
whether the certificate is expired or revoked
-
whether the certificate is trusted on the current machine
-
the state of the XMLSignatureValidator object (such as whether
additional certificates have been added for building the trust chain,
whether those certificates are trusted, and the values of the
useSystemTrustStore
and
revocationCheckSettings
properties)
The
identityStatus
property
can have the following values:
-
valid
— To be considered valid, the
signing certificate must meet the following conditions:
-
The signing certificate must be unaltered.
-
The signing certificate must not be expired or revoked—except
when a valid timestamp is present in the signature. If the signature
is timestamped, the certificate will be considered valid as long
as it was valid at the time the document was signed. (The certificate
used by the timestamp service to sign the timestamp must chain to
a trusted root certificate on the user’s computer.)
-
The signing certificate is trusted. A certificate is trusted
if the certificate is in the system trust store or chains to another
certificate in the system trust store and you set the
useSystemTrustStore
property
to true. You can also designate a certificate as trusted using the
addCertificate()
method
of the XMLSignatureValidator object.
-
The certificate is, in fact, the signing certificate.
-
invalid
— The certificate is expired or
revoked—and no timestamp proving validity at the time of signing
is present—or the certificate has been altered.
-
unknown
— If the certificate is not invalid,
but is not trusted either. Self-signed certificates, for example,
will be reported as
unknown
(unless explicitly trusted).
The
identityStatus
is also reported as
unknown
if
the
verify()
method has not completed without error
or if the identity has not been checked because the signature digest
is invalid.
The referencesStatus property
The
referencesStatus
property reports the cryptographic
integrity of the references in the SignedData element of the signature.
-
valid
— If the computed digest of every
reference in the signature matches the corresponding digest recorded
in the XML signature. A
valid
status indicates
that the signed data has not been altered.
-
invalid
— If any computed digest does not
match the corresponding digest in the signature.
-
unknown
— If the reference digests have
not been checked. The references are not checked if the overall
signature digest is
invalid
or the signing certificate
is invalid. If the
identityStatus
is
unknown
,
then the references are only checked when the
referencesValidationSetting
is
validOrUnknown
.
|
|
|