* of the corresponding <code>SignedData</code>.
*/
public Verifier(Signable sigdat, SignerInfo info, X509Certificate cert)
throws GeneralSecurityException {
AlgorithmParameterSpec spec;
ASN1ObjectIdentifier oid;
ASN1OctetString octets;
Attributes attributes;
Attribute attribute;
String sigalg;
String mdalg;
/*
* Either a certificate or a SignerInfo is needed. We might do without
* one of'em but not without both. The SignedData is need in every case.
*/
if (info == null && cert == null) {
throw new IllegalArgumentException(
"Need either a SignerInfo or a certificate!");
}
if (sigdat == null) {
throw new NullPointerException("Need a SignedData!");
}
target_ = sigdat;
/*
* If the SignerInfo is null then we try to get it from the SignedData.
*/
if (info == null) {
info = target_.getSignerInfo(cert);
if (info == null) {
throw new NoSuchSignerException("No signer info found for: "
+ cert.getIssuerDN().getName() + ", "
+ cert.getSerialNumber());
}
}
/*
* If we have a SignerInfo but no certificate the we try and see if we
* can get it from the SignedData.
*/
else if (cert == null) {
cert = target_.getCertificate(info.getIssuerDN(), info
.getSerialNumber());
if (cert == null) {
throw new CertificateException("No certificate available for: "
+ info.getIssuerDN().getName() + ", "
+ info.getSerialNumber());
}
}
/*
* We have both a SignerInfo and a certificate, now let's see if they
* have matching issuer and serial number.
*/
else {
if (!info.equivIssuerAndSerialNumber(cert)) {
throw new IllegalArgumentException(
"SignerInfo and certificate don't match!");
}
}
/*
* At this point we should have both a SignerInfo and a matching
* certificate.
*/
info_ = info;
cert_ = cert;
sigalg = info_.getAlgorithm();
/*
* We now check for a simple one-step verification or a two-step
* verification. One-step occurs only in the degenerate case that the
* content type of the SignedData instance is DATA and there are no
* authenticated attributes in it.
*
* Otherwise we have to check painfully for the various details on
* required attributes.
*/
attributes = info_.authenticatedAttributes();
oid = target_.getContentType();
if (attributes.size() > 0 || !oid.equals(DATA)) {
twostep_ = true;
attribute = info_.authenticatedAttributes().getAttribute(
CONTENT_TYPE);
if (attribute == null) {
throw new NoSuchAttributeException(
"ContentType attribute missing!");
}
if (attribute.valueCount() == 0) {
throw new InvalidAttributeException(
"ContentType attribute has no OID!");
}
if (!oid.equals(attribute.valueAt(0))) {
throw new InvalidAttributeException(
"ContentType attribute mismatch!");
}
attribute = info_.authenticatedAttributes().getAttribute(
MESSAGE_DIGEST);