Program: 48133
Project: 48133
Buggy source:
/** 
 * This method performs the signature creation according to BSI TR-03112 part 7.
 * @param cryptoMarker The {@link CryptoMarkerType} containing the SignatureCreationInfo for creating the signature.
 * @param keyReference A byte array containing the reference of the key to use.
 * @param algorithmIdentifier A byte array containing the identifier of the signing algorithm.
 * @param message The message to sign.
 * @param slotHandle The slotHandle identifying the card.
 * @param hashRef The variable contains the reference for the hash algorithm which have to be used.
 * @param hashInfo A HashGenerationInfo object which indicates how the hash computation is to perform.
 * @return A {@link SignResponse} object containing the signature of the <b>message</b>.
 * @throws TLVException Thrown if the TLV creation for the key identifier or algorithm identifier failed.
 * @throws IncorrectParameterException Thrown if the SignatureGenerationInfo does not contain PSO_CDS or INT_AUTHafter an MSE_KEY command.
 * @throws APDUException Thrown if one of the command to create the signature failed.
 * @throws org.openecard.common.WSHelper.WSException Thrown if the checkResults method of WSHelper failed.
 */
private SignResponse performSignature(CryptoMarkerType cryptoMarker,byte[] keyReference,byte[] algorithmIdentifier,byte[] message,byte[] slotHandle,byte[] hashRef,HashGenerationInfoType hashInfo) throws TLVException, IncorrectParameterException, APDUException, WSHelper.WSException {
  SignResponse response=WSHelper.makeResponse(SignResponse.class,WSHelper.makeResultOK());
  TLV tagAlgorithmIdentifier=new TLV();
  tagAlgorithmIdentifier.setTagNumWithClass(CARD_ALG_REF);
  tagAlgorithmIdentifier.setValue(algorithmIdentifier);
  TLV tagKeyReference=new TLV();
  tagKeyReference.setTagNumWithClass(KEY_REFERENCE_PRIVATE_KEY);
  tagKeyReference.setValue(keyReference);
  CardCommandAPDU cmdAPDU=null;
  CardResponseAPDU responseAPDU=null;
  String[] signatureGenerationInfo=cryptoMarker.getSignatureGenerationInfo();
  for (  String command : signatureGenerationInfo) {
    HashSet<String> signGenInfo=new HashSet<String>(java.util.Arrays.asList(signatureGenerationInfo));
    if (command.equals("String_Node_Str")) {
      byte[] mseData=tagKeyReference.toBER();
      if (signGenInfo.contains("String_Node_Str")) {
        cmdAPDU=new ManageSecurityEnvironment(SET_COMPUTATION,ManageSecurityEnvironment.DST,mseData);
      }
 else       if (signGenInfo.contains("String_Node_Str") && !signGenInfo.contains("String_Node_Str")) {
        cmdAPDU=new ManageSecurityEnvironment(SET_COMPUTATION,ManageSecurityEnvironment.AT,mseData);
      }
 else {
        String msg="String_Node_Str";
        logger.error(msg);
        throw new IncorrectParameterException(msg);
      }
    }
 else     if (command.equals("String_Node_Str")) {
      cmdAPDU=new PSOComputeDigitalSignature(message,BLOCKSIZE);
    }
 else     if (command.equals("String_Node_Str")) {
      cmdAPDU=new InternalAuthenticate(message,BLOCKSIZE);
    }
 else     if (command.equals("String_Node_Str")) {
      cmdAPDU=new ManageSecurityEnvironment.Restore(ManageSecurityEnvironment.DST);
    }
 else     if (command.equals("String_Node_Str")) {
      cmdAPDU=new ManageSecurityEnvironment.Set(SET_COMPUTATION,ManageSecurityEnvironment.HT);
      TLV mseDataTLV=new TLV();
      mseDataTLV.setTagNumWithClass((byte)0x80);
      mseDataTLV.setValue(hashRef);
      cmdAPDU.setData(mseDataTLV.toBER());
    }
 else     if (command.equals("String_Node_Str")) {
      if (hashInfo.value().equals(HashGenerationInfoType.LAST_ROUND_ON_CARD.value()) || hashInfo.value().equals(HashGenerationInfoType.NOT_ON_CARD.value())) {
        cmdAPDU=new PSOHash(PSOHash.P2_SET_HASH_OR_PART,message);
      }
 else {
        cmdAPDU=new PSOHash(PSOHash.P2_HASH_MESSAGE,message);
      }
    }
 else     if (command.equals("String_Node_Str")) {
      byte[] mseData=tagAlgorithmIdentifier.toBER();
      cmdAPDU=new ManageSecurityEnvironment(SET_COMPUTATION,ManageSecurityEnvironment.DST,mseData);
    }
 else     if (command.equals("String_Node_Str")) {
      byte[] mseData=ByteUtils.concatenate(tagKeyReference.toBER(),tagAlgorithmIdentifier.toBER());
      cmdAPDU=new ManageSecurityEnvironment(SET_COMPUTATION,ManageSecurityEnvironment.DST,mseData);
    }
 else     if (command.equals("String_Node_Str")) {
      byte[] mseData=tagKeyReference.toBER();
      cmdAPDU=new ManageSecurityEnvironment(SET_COMPUTATION,ManageSecurityEnvironment.AT,mseData);
    }
 else     if (command.equals("String_Node_Str")) {
      byte[] mseData=ByteUtils.concatenate(tagKeyReference.toBER(),tagAlgorithmIdentifier.toBER());
      cmdAPDU=new ManageSecurityEnvironment(SET_COMPUTATION,ManageSecurityEnvironment.AT,mseData);
    }
 else {
      String msg="String_Node_Str" + command + "String_Node_Str";
      throw new IncorrectParameterException(msg);
    }
    responseAPDU=cmdAPDU.transmit(dispatcher,slotHandle,Collections.<byte[]>emptyList());
  }
  byte[] signedMessage=responseAPDU.getData();
  while (responseAPDU.getTrailer()[0] == (byte)0x61) {
    CardCommandAPDU getResponseData=new CardCommandAPDU((byte)0x00,(byte)0xC0,(byte)0x00,(byte)0x00,responseAPDU.getTrailer()[1]);
    responseAPDU=getResponseData.transmit(dispatcher,slotHandle,Collections.<byte[]>emptyList());
    signedMessage=Arrays.concatenate(signedMessage,responseAPDU.getData());
  }
  if (!Arrays.areEqual(responseAPDU.getTrailer(),new byte[]{(byte)0x90,(byte)0x00})) {
    TransmitResponse tr=new TransmitResponse();
    tr.getOutputAPDU().add(responseAPDU.toByteArray());
    WSHelper.checkResult(response);
  }
  response.setSignature(signedMessage);
  return response;
}

Fixed version (ground truth):
/** 
 * This method performs the signature creation according to BSI TR-03112 part 7.
 * @param cryptoMarker The {@link CryptoMarkerType} containing the SignatureCreationInfo for creating the signature.
 * @param keyReference A byte array containing the reference of the key to use.
 * @param algorithmIdentifier A byte array containing the identifier of the signing algorithm.
 * @param message The message to sign.
 * @param slotHandle The slotHandle identifying the card.
 * @param hashRef The variable contains the reference for the hash algorithm which have to be used.
 * @param hashInfo A HashGenerationInfo object which indicates how the hash computation is to perform.
 * @return A {@link SignResponse} object containing the signature of the <b>message</b>.
 * @throws TLVException Thrown if the TLV creation for the key identifier or algorithm identifier failed.
 * @throws IncorrectParameterException Thrown if the SignatureGenerationInfo does not contain PSO_CDS or INT_AUTHafter an MSE_KEY command.
 * @throws APDUException Thrown if one of the command to create the signature failed.
 * @throws org.openecard.common.WSHelper.WSException Thrown if the checkResults method of WSHelper failed.
 */
private SignResponse performSignature(CryptoMarkerType cryptoMarker,byte[] keyReference,byte[] algorithmIdentifier,byte[] message,byte[] slotHandle,byte[] hashRef,HashGenerationInfoType hashInfo) throws TLVException, IncorrectParameterException, APDUException, WSHelper.WSException {
  SignResponse response=WSHelper.makeResponse(SignResponse.class,WSHelper.makeResultOK());
  TLV tagAlgorithmIdentifier=new TLV();
  tagAlgorithmIdentifier.setTagNumWithClass(CARD_ALG_REF);
  tagAlgorithmIdentifier.setValue(algorithmIdentifier);
  TLV tagKeyReference=new TLV();
  tagKeyReference.setTagNumWithClass(KEY_REFERENCE_PRIVATE_KEY);
  tagKeyReference.setValue(keyReference);
  CardCommandAPDU cmdAPDU=null;
  CardResponseAPDU responseAPDU=null;
  String[] signatureGenerationInfo=cryptoMarker.getSignatureGenerationInfo();
  for (  String command : signatureGenerationInfo) {
    HashSet<String> signGenInfo=new HashSet<String>(java.util.Arrays.asList(signatureGenerationInfo));
    if (command.equals("String_Node_Str")) {
      byte[] mseData=tagKeyReference.toBER();
      if (signGenInfo.contains("String_Node_Str")) {
        cmdAPDU=new ManageSecurityEnvironment(SET_COMPUTATION,ManageSecurityEnvironment.DST,mseData);
      }
 else       if (signGenInfo.contains("String_Node_Str") && !signGenInfo.contains("String_Node_Str")) {
        cmdAPDU=new ManageSecurityEnvironment(SET_COMPUTATION,ManageSecurityEnvironment.AT,mseData);
      }
 else {
        String msg="String_Node_Str";
        logger.error(msg);
        throw new IncorrectParameterException(msg);
      }
    }
 else     if (command.equals("String_Node_Str")) {
      cmdAPDU=new PSOComputeDigitalSignature(message,BLOCKSIZE);
    }
 else     if (command.equals("String_Node_Str")) {
      cmdAPDU=new InternalAuthenticate(message,BLOCKSIZE);
    }
 else     if (command.equals("String_Node_Str")) {
      cmdAPDU=new ManageSecurityEnvironment.Restore(ManageSecurityEnvironment.DST);
    }
 else     if (command.equals("String_Node_Str")) {
      cmdAPDU=new ManageSecurityEnvironment.Set(SET_COMPUTATION,ManageSecurityEnvironment.HT);
      TLV mseDataTLV=new TLV();
      mseDataTLV.setTagNumWithClass((byte)0x80);
      mseDataTLV.setValue(hashRef);
      cmdAPDU.setData(mseDataTLV.toBER());
    }
 else     if (command.equals("String_Node_Str")) {
      if (hashInfo.value().equals(HashGenerationInfoType.LAST_ROUND_ON_CARD.value()) || hashInfo.value().equals(HashGenerationInfoType.NOT_ON_CARD.value())) {
        cmdAPDU=new PSOHash(PSOHash.P2_SET_HASH_OR_PART,message);
      }
 else {
        cmdAPDU=new PSOHash(PSOHash.P2_HASH_MESSAGE,message);
      }
    }
 else     if (command.equals("String_Node_Str")) {
      byte[] mseData=tagAlgorithmIdentifier.toBER();
      cmdAPDU=new ManageSecurityEnvironment(SET_COMPUTATION,ManageSecurityEnvironment.DST,mseData);
    }
 else     if (command.equals("String_Node_Str")) {
      byte[] mseData=ByteUtils.concatenate(tagKeyReference.toBER(),tagAlgorithmIdentifier.toBER());
      cmdAPDU=new ManageSecurityEnvironment(SET_COMPUTATION,ManageSecurityEnvironment.DST,mseData);
    }
 else     if (command.equals("String_Node_Str")) {
      byte[] mseData=tagKeyReference.toBER();
      cmdAPDU=new ManageSecurityEnvironment(SET_COMPUTATION,ManageSecurityEnvironment.AT,mseData);
    }
 else     if (command.equals("String_Node_Str")) {
      byte[] mseData=ByteUtils.concatenate(tagKeyReference.toBER(),tagAlgorithmIdentifier.toBER());
      cmdAPDU=new ManageSecurityEnvironment(SET_COMPUTATION,ManageSecurityEnvironment.AT,mseData);
    }
 else {
      String msg="String_Node_Str" + command + "String_Node_Str";
      throw new IncorrectParameterException(msg);
    }
    responseAPDU=cmdAPDU.transmit(dispatcher,slotHandle,Collections.<byte[]>emptyList());
  }
  byte[] signedMessage=responseAPDU.getData();
  while (responseAPDU.getTrailer()[0] == (byte)0x61) {
    GetResponse getResponseData=new GetResponse();
    responseAPDU=getResponseData.transmit(dispatcher,slotHandle,Collections.<byte[]>emptyList());
    signedMessage=Arrays.concatenate(signedMessage,responseAPDU.getData());
  }
  if (!Arrays.areEqual(responseAPDU.getTrailer(),new byte[]{(byte)0x90,(byte)0x00})) {
    TransmitResponse tr=new TransmitResponse();
    tr.getOutputAPDU().add(responseAPDU.toByteArray());
    WSHelper.checkResult(response);
  }
  response.setSignature(signedMessage);
  return response;
}