public static boolean isTestCard(X509Certificate cert) { if (cert != null) { String cn = ConvertUtils.getCommonName(cert.getSubjectDN().getName()); // if(cn != null && cn.indexOf("TEST") != -1) // return true; for (int i = 0; i < TEST_OIDS_PREFS.length; i++) { String sOid = TEST_OIDS_PREFS[i]; if (i == 1) { if (certHasPolicy(cert, sOid) && cn != null && cn.indexOf("TEST") != -1) return true; } else { if (certHasPolicy(cert, sOid)) return true; } } } return false; }
public static Signature finalizeXadesXL_TM(SignedDoc sdoc, Signature sig) throws DigiDocException { if (m_logger.isDebugEnabled()) m_logger.debug("Finalize XAdES-TM: " + sig.getId() + " profile: " + sig.getProfile()); NotaryFactory notFac = ConfigManager.instance().getNotaryFactory(); X509Certificate cert = sig.getKeyInfo().getSignersCertificate(); boolean bUseLocal = ConfigManager.instance().getBooleanProperty("DIGIDOC_USE_LOCAL_TSL", false); TrustServiceFactory tslFac = ConfigManager.instance().getTslFactory(); String ocspUrl = tslFac.findOcspUrlForCert(cert, 0, bUseLocal); if (ocspUrl == null) ocspUrl = ConfigManager.instance().getProperty("DIGIDOC_OCSP_RESPONDER_URL"); X509Certificate caCert = tslFac.findCaForCert(cert, bUseLocal, null); if (m_logger.isDebugEnabled()) m_logger.debug( "Get confirmation for cert: " + ((cert != null) ? ConvertUtils.getCommonName(cert.getSubjectDN().getName()) : "NULL") + " CA: " + ((caCert != null) ? ConvertUtils.getCommonName(caCert.getSubjectDN().getName()) : "NULL") + " URL: " + ((ocspUrl != null) ? ocspUrl : "NONE")); System.out.println("Get conf: " + sig.getId()); Notary not = notFac.getConfirmation(sig, cert, caCert, null, ocspUrl); if (m_logger.isDebugEnabled()) m_logger.debug("Resp-id: " + not.getResponderId()); String sRespId = ConvertUtils.getCommonName(not.getResponderId()); // if(sRespId != null && sRespId.startsWith("byName: ")) sRespId = sRespId.substring("byName: // ".length()); // if(sRespId != null && sRespId.startsWith("byKey: ")) sRespId = sRespId.substring("byKey: // ".length()); X509Certificate rcert = notFac.getNotaryCert(sRespId, not.getCertNr()); if (m_logger.isDebugEnabled()) m_logger.debug( "Find responder cert by: " + sRespId + " and nr: " + not.getCertNr() + " found: " + ((rcert != null) ? "OK" : "NO") + " format: " + sdoc.getFormat()); // if the request was successful then // create new data memebers if (sdoc.getFormat().equals(SignedDoc.FORMAT_BDOC) && (rcert != null)) { X509Certificate rcacert = tslFac.findCaForCert(rcert, bUseLocal, null); if (m_logger.isDebugEnabled()) m_logger.debug( "Register responders CA: " + ((rcacert != null) ? rcacert.getSubjectDN().getName() : "NULL")); String caId = not.getId() + "-" + ConvertUtils.getCommonName(rcacert.getSubjectDN().getName()); registerCert(rcacert, CertID.CERTID_TYPE_RESPONDER_CA, caId, sig); } // add notary to list // sig.getUnsignedProperties().addNotary(not); // add ocsp ref for this notary OcspRef orf = new OcspRef( "#" + not.getId(), not.getResponderId(), not.getProducedAt(), (sdoc.getFormat().equals(SignedDoc.FORMAT_BDOC) ? SignedDoc.SHA256_DIGEST_ALGORITHM_1 : SignedDoc.SHA1_DIGEST_ALGORITHM), SignedDoc.digestOfType( not.getOcspResponseData(), (sdoc.getFormat().equals(SignedDoc.FORMAT_BDOC) ? SignedDoc.SHA256_DIGEST_TYPE : SignedDoc.SHA1_DIGEST_TYPE))); sig.getUnsignedProperties().getCompleteRevocationRefs().addOcspRef(orf); // mark status sig.setProfile(SignedDoc.BDOC_PROFILE_TM); // change profile if (sdoc.getFormat().equals(SignedDoc.FORMAT_BDOC) && sig.getPath() != null) { if (m_logger.isDebugEnabled()) m_logger.debug("Find signature: " + sig.getPath()); ManifestFileEntry mfe = sdoc.findManifestEntryByPath(sig.getPath()); if (mfe != null) { mfe.setMediaType( SignedDoc.MIME_SIGNATURE_BDOC_ + sdoc.getVersion() + "/" + sig.getProfile()); if (m_logger.isDebugEnabled()) m_logger.debug("Change signature: " + sig.getPath() + " type: " + mfe.getMediaType()); } } // TODO: update certs and refs return sig; }
/** * Adds a new uncomplete signature to signed doc * * @param sdoc SignedDoc object * @param profile new signature profile. Use NULL for default * @param cert signers certificate * @param claimedRoles signers claimed roles * @param adr signers address * @param sId new signature id, Use NULL for default value * @param sSigMethod signature method uri - ddoc: SignedDoc.RSA_SHA1_SIGNATURE_METHOD, bdoc: * depends on card type. Use null for default value * @param sDigType digest type (all other hashes but SignedInfo). Use null for default type * @return new Signature object */ public static Signature prepareXadesBES( SignedDoc sdoc, String profile, X509Certificate cert, String[] claimedRoles, SignatureProductionPlace adr, String sId, String sSigMethod, String sDigType) throws DigiDocException { if (m_logger.isDebugEnabled()) m_logger.debug( "Prepare signature in sdoc: " + sdoc.getFormat() + "/" + sdoc.getVersion() + "/" + sdoc.getProfile() + " profile: " + profile + " signer: " + ((cert != null) ? SignedDoc.getCommonName(cert.getSubjectDN().getName()) : "unknown") + " id " + sId); boolean bWeakSig = false; for (int i = 0; i < sdoc.countSignatures(); i++) { Signature sig = sdoc.getSignature(i); if (sig.getAltDigestMatch()) bWeakSig = true; } if (bWeakSig) { m_logger.error( "One or more signatures has wrong DataFile hash even if alternative hash matches!"); throw new DigiDocException( DigiDocException.ERR_VERIFY, "One or more signatures has wrong DataFile hash even if alternative hash matches!", null); } // count roles if (claimedRoles != null && claimedRoles.length > 1) { m_logger.error("Currently supports no more than 1 ClaimedRole"); throw new DigiDocException( DigiDocException.ERR_UNSUPPORTED, "Currently supports no more than 1 ClaimedRole", null); } // cannot proceed if cert has not been read if (cert == null) { m_logger.error("Signers certificate missing during signature preparation!"); throw new DigiDocException( DigiDocException.ERR_SIGNERS_CERT, "Signers certificate missing during signature preparation!", null); } boolean bCheckNonRepu = ConfigManager.instance().getBooleanProperty("KEY_USAGE_CHECK", true); if (bCheckNonRepu && !ConfigManager.isSignatureKey(cert)) { if (m_logger.isDebugEnabled()) m_logger.debug("Signers cert does not have non-repudiation bit set!"); throw new DigiDocException( DigiDocException.ERR_SIGNERS_CERT_NONREPUD, "Signers cert does not have non-repudiation bit set!", null); } Signature sig = new Signature(sdoc); sig.setId(sId != null ? sId : sdoc.getNewSignatureId()); if (profile != null) { // use new profile for this signature sig.setProfile(profile); if (sdoc.getProfile() == null || sdoc.getProfile().equals(SignedDoc.BDOC_PROFILE_BES)) sdoc.setProfile(profile); // change also container to new profile } else // use default profile sig.setProfile(sdoc.getProfile()); // create SignedInfo block SignedInfo si = new SignedInfo( sig, ((sSigMethod != null) ? sSigMethod : SignedDoc.RSA_SHA1_SIGNATURE_METHOD), SignedDoc.CANONICALIZATION_METHOD_20010315); if (sdoc.getFormat().equals(SignedDoc.FORMAT_BDOC) && sdoc.getVersion().equals(SignedDoc.BDOC_VERSION_2_1)) { si.setCanonicalizationMethod(SignedDoc.CANONICALIZATION_METHOD_1_1); sdoc.setDefaultNsPref(SignedDoc.FORMAT_BDOC); } if (m_logger.isDebugEnabled()) m_logger.debug( "Signer: " + cert.getSubjectDN().getName() + " EC key: " + isEcPubKey(cert) + " pre-2011: " + isPre2011IdCard(cert) + " digi-id: " + isDigiIdCard(cert) + " 2011: " + is2011Card(cert)); if (sSigMethod == null) { // default values if (sdoc.getFormat().equals(SignedDoc.FORMAT_BDOC)) { if (isPre2011IdCard(cert)) { if (m_logger.isDebugEnabled()) m_logger.debug("Generating rsa-sha224 signature for pre-2011 card"); si.setSignatureMethod(SignedDoc.RSA_SHA224_SIGNATURE_METHOD); } else { String dType = ConfigManager.instance().getStringProperty("DIGIDOC_DIGEST_TYPE", "SHA-256"); String sSigMeth = ConfigManager.digType2SigMeth(dType, isEcPubKey(cert)); if (m_logger.isDebugEnabled()) m_logger.debug("Generating digest: " + dType + " and signature: " + sSigMeth); if (sSigMeth != null) si.setSignatureMethod(sSigMeth); else throw new DigiDocException( DigiDocException.ERR_DIGEST_ALGORITHM, "Invalid digest type: " + dType, null); } } } if (sdoc.getFormat().equals(SignedDoc.FORMAT_XADES) || sdoc.getFormat().equals(SignedDoc.FORMAT_BDOC)) si.setId(sig.getId() + "-SignedInfo"); // SignedDataObjectProperties SignedDataObjectProperties sdop = new SignedDataObjectProperties(); // add DataFile references for (int i = 0; i < sdoc.countDataFiles(); i++) { DataFile df = sdoc.getDataFile(i); if (sdoc.getFormat().equals(SignedDoc.FORMAT_BDOC)) { if (!df.isDigestsCalculated()) { try { InputStream is = null; if (df.getDfCacheFile() != null) is = df.getBodyAsStream(); if (is == null) is = sdoc.findDataFileAsStream(df.getFileName()); if (is == null) is = new java.io.FileInputStream(df.getFileName()); df.calcHashes(is); } catch (java.io.FileNotFoundException ex) { throw new DigiDocException( DigiDocException.ERR_READ_FILE, "Cannot read file: " + df.getFileName(), null); } } } else { if (!df.isDigestsCalculated()) df.calculateFileSizeAndDigest(null); } if (m_logger.isDebugEnabled()) m_logger.debug("Add ref for df: " + df.getId()); Reference ref = new Reference(si, df, sDigType); if (sdoc.getFormat().equals(SignedDoc.FORMAT_XADES) || sdoc.getFormat().equals(SignedDoc.FORMAT_BDOC)) ref.setId(sig.getId() + "-ref-" + i); si.addReference(ref); if (sdoc.getFormat().equals(SignedDoc.FORMAT_BDOC) && sdoc.getVersion().equals(SignedDoc.BDOC_VERSION_2_1)) { DataObjectFormat dof = new DataObjectFormat("#" + ref.getId()); dof.setMimeType(df.getMimeType()); sdop.addDataObjectFormat(dof); } } // manifest.xml reference - bdoc 2.1-s ei allkirjasta manifest.xml-i // create key info KeyInfo ki = new KeyInfo(cert); if (sdoc.getFormat().equals(SignedDoc.FORMAT_XADES) || sdoc.getFormat().equals(SignedDoc.FORMAT_BDOC)) ki.setId(sig.getId() + "-KeyInfo"); sig.setKeyInfo(ki); ki.setSignature(sig); registerCert(cert, CertValue.CERTVAL_TYPE_SIGNER, null, sig); if (m_logger.isDebugEnabled()) m_logger.debug("Signer cert: " + cert.getSubjectDN().getName()); boolean bUseLocal = ConfigManager.instance().getBooleanProperty("DIGIDOC_USE_LOCAL_TSL", false); if (sdoc.getFormat().equals(SignedDoc.FORMAT_XADES) || sdoc.getFormat().equals(SignedDoc.FORMAT_BDOC)) { TrustServiceFactory tslFac = ConfigManager.instance().getTslFactory(); // first lookup in TSL-s X509Certificate ca = tslFac.findCaForCert(cert, bUseLocal, null); if (ca != null) { String caId = sig.getId() + "-" + ConvertUtils.getCommonName(ca.getSubjectDN().getName()); registerCert(ca, CertValue.CERTVAL_TYPE_CA, caId, sig); } // TODO: maybe copy local CA certs to signature until the first ca that is in TSL? } // create signed properties SignedProperties sp = new SignedProperties(sig, cert, claimedRoles, adr); sig.setSignedProperties(sp); // bdoc 2.0 nonce policy if (sdoc.getFormat().equals(SignedDoc.FORMAT_BDOC) && sdoc.getVersion().equals(SignedDoc.BDOC_VERSION_2_1) && (sig.getProfile().equals(SignedDoc.BDOC_PROFILE_TM) || sig.getProfile().equals(SignedDoc.BDOC_PROFILE_BES) || sig.getProfile().equals(SignedDoc.BDOC_PROFILE_CL) || sig.getProfile().equals(SignedDoc.BDOC_PROFILE_TMA))) { sp.setSignedDataObjectProperties(sdop); Identifier id1 = new Identifier(Identifier.OIDAsURN); id1.setUri(BDOC_210_OID); ObjectIdentifier oid1 = new ObjectIdentifier(id1); SignaturePolicyId spi1 = new SignaturePolicyId(oid1); spi1.setDigestAlgorithm(BDOC_210_DIGEST_METHOD); spi1.setDigestValue(ConvertUtils.hex2bin(BDOC_210_DIGEST_HEX)); // System.out.println("Spec hash: " + BDOC_210_DIGEST_HEX + " b64: " + // Base64Util.encode(ConvertUtils.hex2bin(BDOC_210_DIGEST_HEX))); spi1.addSigPolicyQualifier(new SpUri(BDOC_210_SPURI)); SignaturePolicyIdentifier spid1 = new SignaturePolicyIdentifier(spi1); sp.setSignaturePolicyIdentifier(spid1); } else { SignaturePolicyIdentifier spid1 = new SignaturePolicyIdentifier(null); sp.setSignaturePolicyIdentifier(spid1); } Reference ref = new Reference(si, sp, sDigType); if (sdoc.getFormat().equals(SignedDoc.FORMAT_XADES) || sdoc.getFormat().equals(SignedDoc.FORMAT_BDOC)) ref.setId(sig.getId() + "-ref-sp"); ref.setType(SignedDoc.SIGNEDPROPERTIES_TYPE); si.addReference(ref); sig.setSignedInfo(si); sdoc.addSignature(sig); if (m_logger.isDebugEnabled()) m_logger.debug("Prepared signature: " + sig.getId() + "/" + sig.getProfile()); return sig; }
/** * 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; }