Program: 80246
Project: 80246
Buggy source:
/** 
 * Constructor de la clase. Se crea una cofirma a partir de los datos del firmante y del archivo que contiene las firmas.
 * @param signatureAlgorithm Algoritmo para la firma
 * @param signerCertificateChain Cadena de certificados para la construccion de los parametrosde firma.
 * @param data Archivo que contiene las firmas.
 * @param policy Pol&iacute;tica de firma
 * @param signingCertificateV2 <code>true</code> si se desea usar la versi&oacute;n 2 del atributo <i>Signing Certificate</i> <code>false</code> para usar la versi&oacute;n 1
 * @param keyEntry Clave privada usada para firmar.
 * @param md Huella digital espec&iacute;fica para una firma.
 * @return El archivo de firmas con la nueva firma.
 * @throws java.io.IOException Si ocurre alg&uacute;n problema leyendo o escribiendo los datos
 * @throws java.security.NoSuchAlgorithmException Si no se soporta alguno de los algoritmos de firma o huella digital
 * @throws java.security.cert.CertificateException Si se produce alguna excepci&oacute;n con los certificados de firma.
 * @throws javax.security.cert.CertificateException 
 */
byte[] coSigner(final String signatureAlgorithm,final X509Certificate[] signerCertificateChain,final InputStream data,final AdESPolicy policy,final boolean signingCertificateV2,final PrivateKeyEntry keyEntry,final byte[] md) throws IOException, NoSuchAlgorithmException, CertificateException {
  final ASN1InputStream is=new ASN1InputStream(data);
  final ASN1Sequence dsq=(ASN1Sequence)is.readObject();
  final Enumeration<?> e=dsq.getObjects();
  e.nextElement();
  final ASN1TaggedObject doj=(ASN1TaggedObject)e.nextElement();
  final ASN1Sequence contentSignedData=(ASN1Sequence)doj.getObject();
  final SignedData sd=new SignedData(contentSignedData);
  final ContentInfo encInfo=sd.getEncapContentInfo();
  final DEROctetString contenido=(DEROctetString)encInfo.getContent();
  byte[] contenidoDatos=null;
  if (contenido != null) {
    contenidoDatos=AOUtil.getDataFromInputStream(contenido.getOctetStream());
  }
  ASN1Set certificates=null;
  final ASN1Set certificatesSigned=sd.getCertificates();
  final ASN1EncodableVector vCertsSig=new ASN1EncodableVector();
  final Enumeration<?> certs=certificatesSigned.getObjects();
  while (certs.hasMoreElements()) {
    vCertsSig.add((DEREncodable)certs.nextElement());
  }
  if (signerCertificateChain.length != 0) {
    final List<DEREncodable> ce=new ArrayList<DEREncodable>();
    for (    final X509Certificate element : signerCertificateChain) {
      ce.add(X509CertificateStructure.getInstance(ASN1Object.fromByteArray(element.getEncoded())));
    }
    certificates=SigUtils.fillRestCerts(ce,vCertsSig);
  }
  final String digestAlgorithm=AOSignConstants.getDigestAlgorithmName(signatureAlgorithm);
  final AlgorithmIdentifier digAlgId=SigUtils.makeAlgId(AOAlgorithmID.getOID(digestAlgorithm));
  final TBSCertificateStructure tbs=TBSCertificateStructure.getInstance(ASN1Object.fromByteArray(signerCertificateChain[0].getTBSCertificate()));
  final IssuerAndSerialNumber encSid=new IssuerAndSerialNumber(X500Name.getInstance(tbs.getIssuer()),tbs.getSerialNumber().getValue());
  final SignerIdentifier identifier=new SignerIdentifier(encSid);
  final AlgorithmIdentifier encAlgId=SigUtils.makeAlgId(AOAlgorithmID.getOID("String_Node_Str"));
  final ASN1Set signerInfosSd=sd.getSignerInfos();
  final ASN1EncodableVector signerInfos=new ASN1EncodableVector();
  byte[] messageDigest=md.clone();
  for (int i=0; i < signerInfosSd.size(); i++) {
    final SignerInfo si=new SignerInfo((ASN1Sequence)signerInfosSd.getObjectAt(i));
    final AlgorithmIdentifier algHash=si.getDigestAlgorithm();
    if (algHash.getAlgorithm().toString().equals(AOAlgorithmID.getOID(digestAlgorithm))) {
      final ASN1Set signedAttrib=si.getAuthenticatedAttributes();
      for (int s=0; s < signedAttrib.size(); s++) {
        final ASN1Sequence elemento=(ASN1Sequence)signedAttrib.getObjectAt(s);
        final DERObjectIdentifier oids=(DERObjectIdentifier)elemento.getObjectAt(0);
        if (CMSAttributes.messageDigest.getId().toString().equals(oids.toString())) {
          final DERSet derSetHash=(DERSet)elemento.getObjectAt(1);
          final DEROctetString derHash=(DEROctetString)derSetHash.getObjectAt(0);
          messageDigest=derHash.getOctets();
        }
      }
    }
    signerInfos.add(si);
  }
  ASN1Set signedAttr;
  if (contenidoDatos != null) {
    final ASN1EncodableVector contextExpecific=CAdESUtils.generateSignerInfo(signerCertificateChain[0],digestAlgorithm,contenidoDatos,policy,signingCertificateV2,null,new Date());
    this.signedAttr2=SigUtils.getAttributeSet(new AttributeTable(contextExpecific));
    signedAttr=SigUtils.getAttributeSet(new AttributeTable(contextExpecific));
  }
 else   if (messageDigest != null) {
    final ASN1EncodableVector contextExpecific=CAdESUtils.generateSignerInfo(signerCertificateChain[0],digestAlgorithm,null,policy,signingCertificateV2,messageDigest,new Date());
    this.signedAttr2=SigUtils.getAttributeSet(new AttributeTable(contextExpecific));
    signedAttr=SigUtils.getAttributeSet(new AttributeTable(contextExpecific));
  }
 else {
    throw new IllegalStateException("String_Node_Str");
  }
  final ASN1OctetString sign2;
  try {
    sign2=firma(signatureAlgorithm,keyEntry);
  }
 catch (  final AOException ex) {
    throw new IOException("String_Node_Str" + ex);
  }
  signerInfos.add(new SignerInfo(identifier,digAlgId,signedAttr,encAlgId,sign2,null));
  return new ContentInfo(PKCSObjectIdentifiers.signedData,new SignedData(sd.getDigestAlgorithms(),encInfo,certificates,null,new DERSet(signerInfos))).getDEREncoded();
}

Fixed version (ground truth):
/** 
 * Constructor de la clase. Se crea una cofirma a partir de los datos del firmante y del archivo que contiene las firmas.
 * @param signatureAlgorithm Algoritmo para la firma
 * @param signerCertificateChain Cadena de certificados para la construccion de los parametrosde firma.
 * @param data Archivo que contiene las firmas.
 * @param policy Pol&iacute;tica de firma
 * @param signingCertificateV2 <code>true</code> si se desea usar la versi&oacute;n 2 del atributo <i>Signing Certificate</i> <code>false</code> para usar la versi&oacute;n 1
 * @param keyEntry Clave privada usada para firmar.
 * @param md Huella digital espec&iacute;fica para una firma.
 * @return El archivo de firmas con la nueva firma.
 * @throws java.io.IOException Si ocurre alg&uacute;n problema leyendo o escribiendo los datos
 * @throws java.security.NoSuchAlgorithmException Si no se soporta alguno de los algoritmos de firma o huella digital
 * @throws java.security.cert.CertificateException Si se produce alguna excepci&oacute;n con los certificados de firma.
 * @throws javax.security.cert.CertificateException 
 */
byte[] coSigner(final String signatureAlgorithm,final X509Certificate[] signerCertificateChain,final InputStream data,final AdESPolicy policy,final boolean signingCertificateV2,final PrivateKeyEntry keyEntry,final byte[] md) throws IOException, NoSuchAlgorithmException, CertificateException {
  final ASN1InputStream is=new ASN1InputStream(data);
  final ASN1Sequence dsq=(ASN1Sequence)is.readObject();
  final Enumeration<?> e=dsq.getObjects();
  e.nextElement();
  final ASN1TaggedObject doj=(ASN1TaggedObject)e.nextElement();
  final ASN1Sequence contentSignedData=(ASN1Sequence)doj.getObject();
  final SignedData sd=new SignedData(contentSignedData);
  final ContentInfo encInfo=sd.getEncapContentInfo();
  final DEROctetString contenido=(DEROctetString)encInfo.getContent();
  byte[] contenidoDatos=null;
  if (contenido != null) {
    contenidoDatos=AOUtil.getDataFromInputStream(contenido.getOctetStream());
  }
  ASN1Set certificates=null;
  final ASN1Set certificatesSigned=sd.getCertificates();
  final ASN1EncodableVector vCertsSig=new ASN1EncodableVector();
  final Enumeration<?> certs=certificatesSigned.getObjects();
  while (certs.hasMoreElements()) {
    vCertsSig.add((DEREncodable)certs.nextElement());
  }
  if (signerCertificateChain.length != 0) {
    final List<DEREncodable> ce=new ArrayList<DEREncodable>();
    for (    final X509Certificate element : signerCertificateChain) {
      ce.add(X509CertificateStructure.getInstance(ASN1Object.fromByteArray(element.getEncoded())));
    }
    certificates=SigUtils.fillRestCerts(ce,vCertsSig);
  }
  final String digestAlgorithm=AOSignConstants.getDigestAlgorithmName(signatureAlgorithm);
  final AlgorithmIdentifier digAlgId=SigUtils.makeAlgId(AOAlgorithmID.getOID(digestAlgorithm));
  final TBSCertificateStructure tbs=TBSCertificateStructure.getInstance(ASN1Object.fromByteArray(signerCertificateChain[0].getTBSCertificate()));
  final IssuerAndSerialNumber encSid=new IssuerAndSerialNumber(X500Name.getInstance(tbs.getIssuer()),tbs.getSerialNumber().getValue());
  final SignerIdentifier identifier=new SignerIdentifier(encSid);
  final AlgorithmIdentifier encAlgId=SigUtils.makeAlgId(AOAlgorithmID.getOID("String_Node_Str"));
  final ASN1Set signerInfosSd=sd.getSignerInfos();
  final ASN1EncodableVector signerInfos=new ASN1EncodableVector();
  byte[] messageDigest=md != null ? md.clone() : null;
  for (int i=0; i < signerInfosSd.size(); i++) {
    final SignerInfo si=new SignerInfo((ASN1Sequence)signerInfosSd.getObjectAt(i));
    final AlgorithmIdentifier algHash=si.getDigestAlgorithm();
    if (algHash.getAlgorithm().toString().equals(AOAlgorithmID.getOID(digestAlgorithm))) {
      final ASN1Set signedAttrib=si.getAuthenticatedAttributes();
      for (int s=0; s < signedAttrib.size(); s++) {
        final ASN1Sequence elemento=(ASN1Sequence)signedAttrib.getObjectAt(s);
        final DERObjectIdentifier oids=(DERObjectIdentifier)elemento.getObjectAt(0);
        if (CMSAttributes.messageDigest.getId().toString().equals(oids.toString())) {
          final DERSet derSetHash=(DERSet)elemento.getObjectAt(1);
          final DEROctetString derHash=(DEROctetString)derSetHash.getObjectAt(0);
          messageDigest=derHash.getOctets();
        }
      }
    }
    signerInfos.add(si);
  }
  ASN1Set signedAttr;
  if (contenidoDatos != null) {
    final ASN1EncodableVector contextExpecific=CAdESUtils.generateSignerInfo(signerCertificateChain[0],digestAlgorithm,contenidoDatos,policy,signingCertificateV2,null,new Date());
    this.signedAttr2=SigUtils.getAttributeSet(new AttributeTable(contextExpecific));
    signedAttr=SigUtils.getAttributeSet(new AttributeTable(contextExpecific));
  }
 else   if (messageDigest != null) {
    final ASN1EncodableVector contextExpecific=CAdESUtils.generateSignerInfo(signerCertificateChain[0],digestAlgorithm,null,policy,signingCertificateV2,messageDigest,new Date());
    this.signedAttr2=SigUtils.getAttributeSet(new AttributeTable(contextExpecific));
    signedAttr=SigUtils.getAttributeSet(new AttributeTable(contextExpecific));
  }
 else {
    throw new IllegalStateException("String_Node_Str");
  }
  final ASN1OctetString sign2;
  try {
    sign2=firma(signatureAlgorithm,keyEntry);
  }
 catch (  final AOException ex) {
    throw new IOException("String_Node_Str" + ex);
  }
  signerInfos.add(new SignerInfo(identifier,digAlgId,signedAttr,encAlgId,sign2,null));
  return new ContentInfo(PKCSObjectIdentifiers.signedData,new SignedData(sd.getDigestAlgorithms(),encInfo,certificates,null,new DERSet(signerInfos))).getDEREncoded();
}