*/
private boolean checkScepResponse(byte[] retMsg, String senderNonce, String transId, boolean crlRep, String digestOid, boolean noca, ResponseStatus expectedResponseStatus, String userDN, boolean[] keyUsage) throws CMSException, NoSuchProviderException, NoSuchAlgorithmException, CertStoreException, InvalidKeyException, CertificateException, SignatureException, CRLException, IOException {
//
// Parse response message
//
CMSSignedData s = new CMSSignedData(retMsg);
// The signer, i.e. the CA, check it's the right CA
SignerInformationStore signers = s.getSignerInfos();
Collection<?> col = signers.getSigners();
if ( col.size() <= 0 ) {
StressTest.this.performanceTest.getLog().error("Signers can not be 0");
return false;
}
Iterator<?> iter = col.iterator();
SignerInformation signerInfo = (SignerInformation)iter.next();
// Check that the message is signed with the correct digest alg
if ( !StringUtils.equals(digestOid, signerInfo.getDigestAlgOID()) ) {
StressTest.this.performanceTest.getLog().error("Digest algorithms do not match: "+digestOid+", "+signerInfo.getDigestAlgOID());
return false;
}
SignerId sinfo = signerInfo.getSID();
// Check that the signer is the expected CA
String raCertIssuer = CertTools.stringToBCDNString(this.sessionData.certchain[0].getIssuerDN().getName());
String sinfoIssuer = CertTools.stringToBCDNString(sinfo.getIssuerAsString());
if ( !StringUtils.equals(raCertIssuer, sinfoIssuer) ) {
StressTest.this.performanceTest.getLog().error("Issuers does not match: "+raCertIssuer+", "+sinfoIssuer);
return false;
}
// Verify the signature
boolean ret = signerInfo.verify(this.sessionData.certchain[0].getPublicKey(), "BC");
if ( !ret ) {
StressTest.this.performanceTest.getLog().error("Can not verify signerInfo");
return false;
}
// Get authenticated attributes
AttributeTable tab = signerInfo.getSignedAttributes();
// --Fail info
Attribute attr = tab.get(new DERObjectIdentifier(ScepRequestMessage.id_failInfo));
// No failInfo on this success message
if(expectedResponseStatus == ResponseStatus.SUCCESS){
if ( attr != null ) {
StressTest.this.performanceTest.getLog().error("Success message should have attr == null");
return false;
}
}
// --Message type
attr = tab.get(new DERObjectIdentifier(ScepRequestMessage.id_messageType));
if ( attr == null ) {
StressTest.this.performanceTest.getLog().error("MessageType should not be null for responseStatus: "+expectedResponseStatus);
return false;
}
ASN1Set values = attr.getAttrValues();
if ( values.size() != 1 ) {
StressTest.this.performanceTest.getLog().error("MessageType.AttrValues should be 1: "+values.size());
return false;
}
DERString str = DERPrintableString.getInstance((values.getObjectAt(0)));
String messageType = str.getString();
if ( !StringUtils.equals(messageType, "3") ) {
StressTest.this.performanceTest.getLog().error("MessageType should be 3: "+messageType);
return false;
}
// --Success status
attr = tab.get(new DERObjectIdentifier(ScepRequestMessage.id_pkiStatus));
if ( attr == null ) {
StressTest.this.performanceTest.getLog().error("PKIStatus should not be null");
return false;
}
values = attr.getAttrValues();
if ( values.size() != 1 ) {
StressTest.this.performanceTest.getLog().error("PKIStatus.AttrValues should be 1: "+values.size());
return false;
}
str = DERPrintableString.getInstance((values.getObjectAt(0)));
String responsestatus = str.getString();
if ( !StringUtils.equals(expectedResponseStatus.getValue(), responsestatus) ) {
StressTest.this.performanceTest.getLog().error("ResponseStatus should be "+expectedResponseStatus.getValue()+" but was: "+responsestatus);
return false;
}
// --SenderNonce
attr = tab.get(new DERObjectIdentifier(ScepRequestMessage.id_senderNonce));
if ( attr == null ) {
StressTest.this.performanceTest.getLog().error("SenderNonce should not be null");
return false;
}
values = attr.getAttrValues();
if ( values.size() != 1 ) {
StressTest.this.performanceTest.getLog().error("SenderNonce.AttrValues should be 1: "+values.size());
return false;
}
ASN1OctetString octstr = ASN1OctetString.getInstance(values.getObjectAt(0));
// SenderNonce is something the server came up with, but it should be 16 chars
if ( octstr.getOctets().length != 16 ) {
StressTest.this.performanceTest.getLog().error("SenderNonce should be 16 bytes: "+octstr.getOctets().length);
return false;
}
// --Recipient Nonce
attr = tab.get(new DERObjectIdentifier(ScepRequestMessage.id_recipientNonce));
if ( attr == null ) {
StressTest.this.performanceTest.getLog().error("RecipientNonce should not be null");
return false;
}
values = attr.getAttrValues();
if ( values.size() != 1 ) {
StressTest.this.performanceTest.getLog().error("RecipientNonce.AttrValues should be 1: "+values.size());
return false;
}
octstr = ASN1OctetString.getInstance(values.getObjectAt(0));
// recipient nonce should be the same as we sent away as sender nonce
String nonce = new String(Base64.encode(octstr.getOctets()));
if ( !StringUtils.equals(senderNonce, nonce) ) {
StressTest.this.performanceTest.getLog().error("RecipientNonce should be "+senderNonce+" but was: "+nonce);
return false;
}
// --Transaction ID
attr = tab.get(new DERObjectIdentifier(ScepRequestMessage.id_transId));
if ( attr == null ) {
StressTest.this.performanceTest.getLog().error("TransId should not be null");
return false;
}
values = attr.getAttrValues();
if ( values.size() != 1 ) {
StressTest.this.performanceTest.getLog().error("TransId.AttrValues should be 1: "+values.size());
return false;
}
str = DERPrintableString.getInstance((values.getObjectAt(0)));
// transid should be the same as the one we sent
if ( !StringUtils.equals(transId, str.getString()) ) {
StressTest.this.performanceTest.getLog().error("TransId should be "+transId+" but was: "+str.getString());
return false;
}
//
// Check different message types
//
if ( responsestatus.equals(ResponseStatus.PENDING.getValue()) || !messageType.equals("3") ) {
return true;
}
// First we extract the encrypted data from the CMS enveloped data contained
// within the CMS signed data
final CMSProcessable sp = s.getSignedContent();
final byte content[] = (byte[])sp.getContent();
final CMSEnvelopedData ed = new CMSEnvelopedData(content);
final RecipientInformationStore recipients = ed.getRecipientInfos();
final RecipientInformation recipient;
{
final Collection<?> c = recipients.getRecipients();
if ( c.size() != 1 ) {
StressTest.this.performanceTest.getLog().error("recipients should be 1: "+c.size());
return false;
}
final Iterator<?> it = c.iterator();
recipient = (RecipientInformation) it.next();
}
final byte decBytes[] = recipient.getContent(StressTest.this.keyPair.getPrivate(), "BC");
// This is yet another CMS signed data
final CMSSignedData sd = new CMSSignedData(decBytes);
// Get certificates from the signed data
final CertStore certstore = sd.getCertificatesAndCRLs("Collection","BC");
if (crlRep) {
// We got a reply with a requested CRL
final Collection<?> crls = certstore.getCRLs(null);
if ( crls.size() != 1 ) {
StressTest.this.performanceTest.getLog().error("CRLS should be 1: "+crls.size());