/**
  * Method returns a digital signature. It finds the RSA private key object from the active token
  * and then signs the given data with this key and RSA mechanism.
  *
  * @param digest digest of the data to be signed.
  * @param token token index
  * @param passwd users pin code or in case of pkcs12 file password
  * @param sig Signature object to provide info about desired signature method
  * @return an array of bytes containing digital signature.
  * @throws DigiDocException if signing the data fails.
  */
 public byte[] sign(byte[] xml, int token, String passwd, Signature sig) throws DigiDocException {
   try {
     if (m_keyStore == null)
       throw new DigiDocException(
           DigiDocException.ERR_NOT_INITED, "Keystore not initialized", null);
     String alias = getTokenName(token);
     if (alias == null)
       throw new DigiDocException(
           DigiDocException.ERR_TOKEN_LOGIN, "Invalid token nr: " + token, null);
     // get key
     if (m_logger.isDebugEnabled())
       m_logger.debug(
           "loading key: " + alias + " passwd-len: " + ((passwd != null) ? passwd.length() : 0));
     Key key = m_keyStore.getKey(alias, passwd.toCharArray());
     if (m_logger.isDebugEnabled())
       m_logger.debug("Key: " + ((key != null) ? "OK, algorithm: " + key.getAlgorithm() : "NULL"));
     if (key == null)
       throw new DigiDocException(
           DigiDocException.ERR_TOKEN_LOGIN, "Invalid password for token nr: " + token, null);
     String sigMeth = null;
     if (sig != null
         && sig.getSignedInfo() != null
         && sig.getSignedInfo().getSignatureMethod() != null)
       sigMeth = sig.getSignedInfo().getSignatureMethod();
     if (m_logger.isDebugEnabled())
       m_logger.debug("Signing\n---\n" + new String(xml) + "\n---\n method: " + sigMeth);
     java.security.Signature instance = sigMeth2SigSignatureInstance(sig, key);
     if (m_logger.isDebugEnabled())
       m_logger.debug("Signature instance: " + ((instance != null) ? "OK" : "NULL"));
     instance.initSign((PrivateKey) key);
     instance.update(xml);
     byte[] signature = instance.sign();
     boolean bEcCvcKey = isCvcEcKey(sig);
     if (m_logger.isDebugEnabled())
       m_logger.debug(
           "Signature algorithm: "
               + key.getAlgorithm()
               + " siglen: "
               + signature.length
               + " ec-key: "
               + bEcCvcKey);
     if (bEcCvcKey) {
       int nKeyLen = ((ECPrivateKey) key).getParams().getCurve().getField().getFieldSize();
       int nReqLen = ((int) Math.ceil((double) nKeyLen / 8)) * 2;
       int nSigLen = signature.length;
       if (m_logger.isDebugEnabled())
         m_logger.debug("EC Signature length: " + nSigLen + " required: " + nReqLen);
       if (nSigLen < nReqLen) {
         if (m_logger.isDebugEnabled())
           m_logger.debug("Padding EC signature length: " + nSigLen + " to required: " + nReqLen);
         byte[] padsig = new byte[nReqLen];
         System.arraycopy(signature, 0, padsig, (nReqLen - nSigLen) / 2, nSigLen / 2);
         System.arraycopy(
             signature, nSigLen / 2, padsig, (nReqLen / 2) + (nReqLen - nSigLen) / 2, nSigLen / 2);
         signature = padsig;
       }
     }
     if (m_logger.isDebugEnabled() && signature != null)
       m_logger.debug(
           "Signature len: "
               + signature.length
               + "\n---\n sig: "
               + ConvertUtils.bin2hex(signature));
     return signature;
   } catch (DigiDocException ex) {
     m_logger.error("DigiDoc Error signing: " + ex);
     throw ex;
   } catch (Exception ex) {
     m_logger.error("Error signing: " + ex);
   }
   return null;
 }