public static void main(String[] args) throws Exception { // Generate 20 serial numbers with dup and a special order int count = 20; BigInteger[] serials = new BigInteger[count]; for (int i = 0; i < count; i++) { serials[i] = BigInteger.valueOf(i * 7 % 10); } // Generates a CRL X509CRLEntry[] badCerts = new X509CRLEntry[count]; for (int i = 0; i < count; i++) { badCerts[i] = new X509CRLEntryImpl(serials[i], new Date(System.currentTimeMillis() + i * 1000)); } X500Name owner = new X500Name("CN=CA"); X509CRLImpl crl = new X509CRLImpl(owner, new Date(), new Date(), badCerts); KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); crl.sign(kpg.genKeyPair().getPrivate(), "SHA1withRSA"); byte[] data = crl.getEncodedInternal(); // Check the encoding checkData(crl, data, serials); // Load a CRL from raw data CertificateFactory cf = CertificateFactory.getInstance("X.509"); X509CRLImpl crl2 = (X509CRLImpl) cf.generateCRL(new ByteArrayInputStream(data)); // Check the encoding again data = crl2.getEncodedInternal(); checkData(crl2, data, serials); }
private X509CRL decode(byte[] encoded) throws CertificateException, IOException, CRLException { InputStream inStream = new ByteArrayInputStream(encoded); CertificateFactory cf = CertificateFactory.getInstance("X.509"); // $NON-NLS-1$ X509CRL crl = (X509CRL) cf.generateCRL(inStream); inStream.close(); return crl; }
/** * Reads in a X509CRL. * * @return the X509Certificate * @throws IOException if an I/O error occured */ private X509CRL readCRL(String endMarker) throws IOException { ByteArrayInputStream bIn = new ByteArrayInputStream(readBytes(endMarker)); try { CertificateFactory certFact = CertificateFactory.getInstance("X.509", provider); return (X509CRL) certFact.generateCRL(bIn); } catch (Exception e) { throw new PEMException("problem parsing cert: " + e.toString(), e); } }
/** * Gets a list of X509CRL objects from a Document Security Store. * * @return a list of CRLs * @throws GeneralSecurityException * @throws IOException */ public List<X509CRL> getCRLsFromDSS() throws GeneralSecurityException, IOException { List<X509CRL> crls = new ArrayList<X509CRL>(); if (dss == null) return crls; PdfArray crlarray = dss.getAsArray(PdfName.CRLS); if (crlarray == null) return crls; CertificateFactory cf = CertificateFactory.getInstance("X.509"); for (int i = 0; i < crlarray.size(); i++) { PRStream stream = (PRStream) crlarray.getAsStream(i); X509CRL crl = (X509CRL) cf.generateCRL(new ByteArrayInputStream(PdfReader.getStreamBytes(stream))); crls.add(crl); } return crls; }
@JSFunction public X509CRL makeCRL(String fileName) { try { FileInputStream crlFile = new FileInputStream(fileName); try { CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); return (X509CRL) certFactory.generateCRL(crlFile); } catch (CertificateException e) { throw new EvaluatorException("Error opening trust store: " + e); } catch (CRLException e) { throw new EvaluatorException("Error opening trust store: " + e); } finally { crlFile.close(); } } catch (IOException ioe) { throw new EvaluatorException("I/O error reading trust store: " + ioe); } }
private void checkCircProcessing() throws Exception { CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); X509Certificate caCert = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(circCA)); X509Certificate crlCaCert = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(circCRLCA)); X509CRL crl = (X509CRL) cf.generateCRL(new ByteArrayInputStream(circCRL)); List list = new ArrayList(); list.add(caCert); list.add(crlCaCert); list.add(crl); CertStoreParameters ccsp = new CollectionCertStoreParameters(list); CertStore store = CertStore.getInstance("Collection", ccsp); Date validDate = new Date(crl.getThisUpdate().getTime() + 60 * 60 * 1000); // validating path List certchain = new ArrayList(); certchain.add(crlCaCert); CertPath cp = CertificateFactory.getInstance("X.509", "BC").generateCertPath(certchain); Set trust = new HashSet(); trust.add(new TrustAnchor(caCert, null)); CertPathValidator cpv = CertPathValidator.getInstance("PKIX", "BC"); // PKIXParameters param = new PKIXParameters(trust); PKIXBuilderParameters param = new PKIXBuilderParameters(trust, null); X509CertSelector certSelector = new X509CertSelector(); certSelector.setCertificate(crlCaCert); param.setTargetCertConstraints(certSelector); param.addCertStore(store); param.setRevocationEnabled(true); param.setDate(validDate); PKIXCertPathValidatorResult result = (PKIXCertPathValidatorResult) cpv.validate(cp, param); }
/** * Reads in a X509CRL. * * @return the X509CRL * @throws IOException if an I/O error occured */ private static X509CRL readCRL(BufferedReader in, String endMarker) throws IOException { String line; StringBuffer buf = new StringBuffer(); while ((line = in.readLine()) != null) { if (line.indexOf(endMarker) != -1) { break; } buf.append(line.trim()); } if (line == null) { throw new IOException(endMarker + " not found"); } try { CertificateFactory certFact = CertificateFactory.getInstance("X.509"); ByteArrayInputStream bIn = new ByteArrayInputStream(Base64.decode(buf.toString())); return (X509CRL) certFact.generateCRL(bIn); } catch (Exception e) { throw new IOException("problem parsing cert: " + e.toString()); } }
public void performTest() throws Exception { CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); // initialise CertStore X509Certificate rootCert = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(CertPathTest.rootCertBin)); X509Certificate interCert = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(CertPathTest.interCertBin)); X509Certificate finalCert = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(CertPathTest.finalCertBin)); X509CRL rootCrl = (X509CRL) cf.generateCRL(new ByteArrayInputStream(CertPathTest.rootCrlBin)); X509CRL interCrl = (X509CRL) cf.generateCRL(new ByteArrayInputStream(CertPathTest.interCrlBin)); List list = new ArrayList(); list.add(rootCert); list.add(interCert); list.add(finalCert); list.add(rootCrl); list.add(interCrl); CollectionCertStoreParameters ccsp = new CollectionCertStoreParameters(list); CertStore store = CertStore.getInstance("Collection", ccsp, "BC"); Date validDate = new Date(rootCrl.getThisUpdate().getTime() + 60 * 60 * 1000); // validating path List certchain = new ArrayList(); certchain.add(finalCert); certchain.add(interCert); CertPath cp = CertificateFactory.getInstance("X.509", "BC").generateCertPath(certchain); Set trust = new HashSet(); trust.add(new TrustAnchor(rootCert, null)); CertPathValidator cpv = CertPathValidator.getInstance("PKIX", "BC"); PKIXParameters param = new PKIXParameters(trust); param.addCertStore(store); param.setDate(validDate); MyChecker checker = new MyChecker(); param.addCertPathChecker(checker); PKIXCertPathValidatorResult result = (PKIXCertPathValidatorResult) cpv.validate(cp, param); PolicyNode policyTree = result.getPolicyTree(); PublicKey subjectPublicKey = result.getPublicKey(); if (checker.getCount() != 2) { fail("checker not evaluated for each certificate"); } if (!subjectPublicKey.equals(finalCert.getPublicKey())) { fail("wrong public key returned"); } // // invalid path containing a valid one test // try { // initialise CertStore rootCert = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(AC_RAIZ_ICPBRASIL)); interCert = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(AC_PR)); finalCert = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(schefer)); list = new ArrayList(); list.add(rootCert); list.add(interCert); list.add(finalCert); ccsp = new CollectionCertStoreParameters(list); store = CertStore.getInstance("Collection", ccsp); validDate = new Date(finalCert.getNotBefore().getTime() + 60 * 60 * 1000); // validating path certchain = new ArrayList(); certchain.add(finalCert); certchain.add(interCert); cp = CertificateFactory.getInstance("X.509", "BC").generateCertPath(certchain); trust = new HashSet(); trust.add(new TrustAnchor(rootCert, null)); cpv = CertPathValidator.getInstance("PKIX", "BC"); param = new PKIXParameters(trust); param.addCertStore(store); param.setRevocationEnabled(false); param.setDate(validDate); result = (PKIXCertPathValidatorResult) cpv.validate(cp, param); policyTree = result.getPolicyTree(); subjectPublicKey = result.getPublicKey(); fail("Invalid path validated"); } catch (Exception e) { if (!(e instanceof CertPathValidatorException && e.getMessage().startsWith("Could not validate certificate signature."))) { fail("unexpected exception", e); } } checkCircProcessing(); checkPolicyProcessingAtDomainMatch(); validateWithExtendedKeyUsage(); testEmptyPath(); }
/** * Parse an encoded PKCS#7 SignedData object. The ASN.1 format of this object is: * * <pre> * SignedData ::= SEQUENCE { * version Version, -- always 1 for PKCS7 v1.5 * digestAlgorithms DigestAlgorithmIdentifiers, * contentInfo ContentInfo, * certificates [0] IMPLICIT ExtendedCertificatesAndCertificates OPTIONAL, * crls [1] IMPLICIT CertificateRevocationLists OPTIONAL, * signerInfos SignerInfos } * * Version ::= INTEGER * * DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier * * DigestAlgorithmIdentifier ::= AlgorithmIdentifier * * ContentInfo ::= SEQUENCE { * contentType ContentType, * content [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL } * * ContentType ::= OBJECT IDENTIFIER * * ExtendedCertificatesAndCertificates ::= * SET OF ExtendedCertificatesAndCertificate * * ExtendedCertificatesAndCertificate ::= CHOICE { * certificate Certificate, -- from X.509 * extendedCertificate [0] IMPLICIT ExtendedCertificate } * * CertificateRevocationLists ::= SET OF CertificateRevocationList * -- from X.509 * * SignerInfos ::= SET OF SignerInfo * * SignerInfo ::= SEQUENCE { * version Version, -- always 1 for PKCS7 v1.5 * issuerAndSerialNumber IssuerAndSerialNumber, * digestAlgorithm DigestAlgorithmIdentifier, * authenticatedAttributes [0] IMPLICIT Attributes OPTIONAL, * digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier, * encryptedDigest EncryptedDigest, * unauthenticatedAttributes [1] IMPLICIT Attributes OPTIONAL } * * EncryptedDigest ::= OCTET STRING * </pre> * * <p>(Readers who are confused as to why it takes 40 levels of indirection to specify "data with * a signature", rest assured that the present author is as confused as you are). */ public PKCS7SignedData(BERReader ber) throws CRLException, CertificateException, IOException { CertificateFactory x509 = CertificateFactory.getInstance("X509"); DERValue val = ber.read(); if (!val.isConstructed()) throw new BEREncodingException("malformed ContentInfo"); val = ber.read(); if (val.getTag() != BER.OBJECT_IDENTIFIER) throw new BEREncodingException("malformed ContentType"); if (!PKCS7_SIGNED_DATA.equals(val.getValue())) throw new BEREncodingException("content is not SignedData"); val = ber.read(); if (val.getTag() != 0) throw new BEREncodingException("malformed Content"); val = ber.read(); if (!val.isConstructed()) throw new BEREncodingException("malformed SignedData"); if (Configuration.DEBUG) log.fine("SignedData: " + val); val = ber.read(); if (val.getTag() != BER.INTEGER) throw new BEREncodingException("expecting Version"); version = (BigInteger) val.getValue(); if (Configuration.DEBUG) log.fine(" Version: " + version); digestAlgorithms = new HashSet(); val = ber.read(); if (!val.isConstructed()) throw new BEREncodingException("malformed DigestAlgorithmIdentifiers"); if (Configuration.DEBUG) log.fine(" DigestAlgorithmIdentifiers: " + val); int count = 0; DERValue val2 = ber.read(); while (val2 != BER.END_OF_SEQUENCE && (val.getLength() > 0 && val.getLength() > count)) { if (!val2.isConstructed()) throw new BEREncodingException("malformed AlgorithmIdentifier"); if (Configuration.DEBUG) log.fine(" AlgorithmIdentifier: " + val2); count += val2.getEncodedLength(); val2 = ber.read(); if (val2.getTag() != BER.OBJECT_IDENTIFIER) throw new BEREncodingException("malformed AlgorithmIdentifier"); if (Configuration.DEBUG) log.fine(" digestAlgorithmIdentifiers OID: " + val2.getValue()); List algId = new ArrayList(2); algId.add(val2.getValue()); val2 = ber.read(); if (val2 != BER.END_OF_SEQUENCE) { count += val2.getEncodedLength(); if (val2.getTag() == BER.NULL) algId.add(null); else algId.add(val2.getEncoded()); if (val2.isConstructed()) ber.skip(val2.getLength()); if (BERValue.isIndefinite(val)) val2 = ber.read(); } else algId.add(null); if (Configuration.DEBUG) { log.fine(" digestAlgorithmIdentifiers params: "); log.fine( Util.dumpString((byte[]) algId.get(1), " digestAlgorithmIdentifiers params: ")); } digestAlgorithms.add(algId); } val = ber.read(); if (!val.isConstructed()) throw new BEREncodingException("malformed ContentInfo"); if (Configuration.DEBUG) log.fine(" ContentInfo: " + val); val2 = ber.read(); if (val2.getTag() != BER.OBJECT_IDENTIFIER) throw new BEREncodingException("malformed ContentType"); contentType = (OID) val2.getValue(); if (Configuration.DEBUG) log.fine(" ContentType OID: " + contentType); if (BERValue.isIndefinite(val) || (val.getLength() > 0 && val.getLength() > val2.getEncodedLength())) { val2 = ber.read(); if (val2 != BER.END_OF_SEQUENCE) { content = val2.getEncoded(); if (BERValue.isIndefinite(val)) val2 = ber.read(); } } if (Configuration.DEBUG) { log.fine(" Content: "); log.fine(Util.dumpString(content, " Content: ")); } val = ber.read(); if (val.getTag() == 0) { if (!val.isConstructed()) throw new BEREncodingException("malformed ExtendedCertificatesAndCertificates"); if (Configuration.DEBUG) log.fine(" ExtendedCertificatesAndCertificates: " + val); count = 0; val2 = ber.read(); List certs = new LinkedList(); while (val2 != BER.END_OF_SEQUENCE && (val.getLength() > 0 && val.getLength() > count)) { Certificate cert = x509.generateCertificate(new ByteArrayInputStream(val2.getEncoded())); if (Configuration.DEBUG) log.fine(" Certificate: " + cert); certs.add(cert); count += val2.getEncodedLength(); ber.skip(val2.getLength()); if (BERValue.isIndefinite(val) || val.getLength() > count) val2 = ber.read(); } certificates = (Certificate[]) certs.toArray(new Certificate[certs.size()]); val = ber.read(); } if (val.getTag() == 1) { if (!val.isConstructed()) throw new BEREncodingException("malformed CertificateRevocationLists"); if (Configuration.DEBUG) log.fine(" CertificateRevocationLists: " + val); count = 0; val2 = ber.read(); List crls = new LinkedList(); while (val2 != BER.END_OF_SEQUENCE && (val.getLength() > 0 && val.getLength() > count)) { CRL crl = x509.generateCRL(new ByteArrayInputStream(val2.getEncoded())); if (Configuration.DEBUG) log.fine(" CRL: " + crl); crls.add(crl); count += val2.getEncodedLength(); ber.skip(val2.getLength()); if (BERValue.isIndefinite(val) || val.getLength() > count) val2 = ber.read(); } this.crls = (CRL[]) crls.toArray(new CRL[crls.size()]); val = ber.read(); } signerInfos = new HashSet(); if (!val.isConstructed()) throw new BEREncodingException("malformed SignerInfos"); if (Configuration.DEBUG) log.fine(" SignerInfos: " + val); // FIXME read this more carefully. // Since we are just reading a file (probably) we just read until we // reach the end. while (true) { int i = ber.peek(); if (i == 0 || i == -1) break; signerInfos.add(new SignerInfo(ber)); } }
public synchronized boolean checkCRL(X509Certificate cert) throws CertificateException { CRL crl = null; long now = System.currentTimeMillis(); if (now - creationTime > 24 * 60 * 60 * 1000) { // Expire cache every 24 hours if (tempCRLFile != null && tempCRLFile.exists()) { tempCRLFile.delete(); } tempCRLFile = null; passedTest.clear(); /* Note: if any certificate ever fails the check, we will remember that fact. This breaks with temporary "holds" that CRL's can issue. Apparently a certificate can have a temporary "hold" on its validity, but I'm not interested in supporting that. If a "held" certificate is suddenly "unheld", you're just going to need to restart your JVM. */ // failedTest.clear(); <-- DO NOT UNCOMMENT! } BigInteger fingerprint = getFingerprint(cert); if (failedTest.contains(fingerprint)) { throw new CertificateException("Revoked by CRL (cached response)"); } if (passedTest.contains(fingerprint)) { return true; } if (tempCRLFile == null) { try { // log.info( "Trying to load CRL [" + urlString + "]" ); URL url = new URL(urlString); File tempFile = File.createTempFile("crl", ".tmp"); tempFile.deleteOnExit(); OutputStream out = new FileOutputStream(tempFile); out = new BufferedOutputStream(out); InputStream in = new BufferedInputStream(url.openStream()); try { Util.pipeStream(in, out); } catch (IOException ioe) { // better luck next time tempFile.delete(); throw ioe; } this.tempCRLFile = tempFile; this.creationTime = System.currentTimeMillis(); } catch (IOException ioe) { // log.warn( "Cannot check CRL: " + e ); } } if (tempCRLFile != null && tempCRLFile.exists()) { try { InputStream in = new FileInputStream(tempCRLFile); in = new BufferedInputStream(in); synchronized (CF) { crl = CF.generateCRL(in); } in.close(); if (crl.isRevoked(cert)) { // log.warn( "Revoked by CRL [" + urlString + "]: " + name ); passedTest.remove(fingerprint); failedTest.add(fingerprint); throw new CertificateException("Revoked by CRL"); } else { passedTest.add(fingerprint); } } catch (IOException ioe) { // couldn't load CRL that's supposed to be stored in Temp file. // log.warn( ); } catch (CRLException crle) { // something is wrong with the CRL // log.warn( ); } } return crl != null; }
private void loadCrl(String crlFilename) throws IOException, CRLException { InputStream is = load(crlFilename); crl = factory.generateCRL(is); }
@JRubyMethod(name = "initialize", rest = true, frame = true) public IRubyObject _initialize(IRubyObject[] args, Block block) { extensions = new ArrayList<IRubyObject>(); if (org.jruby.runtime.Arity.checkArgumentCount(getRuntime(), args, 0, 1) == 0) { version = getRuntime().getNil(); issuer = getRuntime().getNil(); last_update = getRuntime().getNil(); next_update = getRuntime().getNil(); revoked = getRuntime().newArray(); return this; } ByteArrayInputStream bis = new ByteArrayInputStream(args[0].convertToString().getBytes()); try { // SunJCE throws java.security.cert.CRLException: Invalid encoding of // AuthorityKeyIdentifierExtension. // FIXME: use BC for now. CertificateFactory cf = OpenSSLReal.getX509CertificateFactoryBC(); crl = (java.security.cert.X509CRL) cf.generateCRL(bis); } catch (GeneralSecurityException gse) { throw newX509CRLError(getRuntime(), gse.getMessage()); } byte[] crl_bytes = args[0].convertToString().getBytes(); // Parse PEM if we ever get passed some PEM contents try { StringReader in = new StringReader(args[0].toString()); byte[] bytes = OpenSSLReal.getFormatHandler().readPEMToDER(in); if (bytes != null) crl_bytes = bytes; in.close(); } catch (Exception e) { // this is not PEM encoded, let's use the default argument } try { crl_v = new ASN1InputStream(new ByteArrayInputStream(crl_bytes)).readObject(); } catch (IOException ioe) { throw newX509CRLError(getRuntime(), ioe.getMessage()); } DEREncodable v0 = ((DERSequence) (((DERSequence) crl_v).getObjectAt(0))).getObjectAt(0); if (v0 instanceof DERInteger) { set_version(getRuntime().newFixnum(((DERInteger) v0).getValue().intValue())); } else { set_version(getRuntime().newFixnum(2)); } set_last_update(RubyTime.newTime(getRuntime(), crl.getThisUpdate().getTime())); set_next_update(RubyTime.newTime(getRuntime(), crl.getNextUpdate().getTime())); RubyString name = RubyString.newString(getRuntime(), crl.getIssuerX500Principal().getEncoded()); set_issuer(Utils.newRubyInstance(getRuntime(), "OpenSSL::X509::Name", name)); revoked = getRuntime().newArray(); DERSequence seqa = (DERSequence) ((DERSequence) crl_v).getObjectAt(0); DERObject maybe_ext = (DERObject) seqa.getObjectAt(seqa.size() - 1); if (maybe_ext instanceof DERTaggedObject && ((DERTaggedObject) maybe_ext).getTagNo() == 0) { DERSequence exts = (DERSequence) ((DERTaggedObject) maybe_ext).getObject(); for (int i = 0; i < exts.size(); i++) { DERSequence seq2 = (DERSequence) exts.getObjectAt(i); boolean critical = false; String oid = ((DERObjectIdentifier) seq2.getObjectAt(0)).getId(); if (seq2.getObjectAt(1) == DERBoolean.TRUE) { critical = true; } byte[] value = crl.getExtensionValue(oid); IRubyObject mASN1 = getRuntime().getClassFromPath("OpenSSL::ASN1"); IRubyObject rValue = null; try { rValue = ASN1.decode( mASN1, ASN1.decode(mASN1, RubyString.newString(getRuntime(), value)) .callMethod(getRuntime().getCurrentContext(), "value")); } catch (Exception e) { rValue = RubyString.newString(getRuntime(), value); } X509Extensions.Extension ext1 = (X509Extensions.Extension) Utils.newRubyInstance(getRuntime(), "OpenSSL::X509::Extension"); ext1.setRealOid(ext1.getObjectIdentifier(oid)); ext1.setRealValue(rValue); ext1.setRealCritical(critical); add_extension(ext1); } } changed = false; return this; }
/** * Build Java CRL from base64 encoding. * * @param base64CRL base64-encoded CRL * @return a native Java X509 CRL * @throws CertificateException thrown if there is an error constructing certificate * @throws CRLException thrown if there is an error constructing CRL */ public static java.security.cert.X509CRL buildJavaX509CRL(String base64CRL) throws CertificateException, CRLException { CertificateFactory cf = CertificateFactory.getInstance("X.509"); ByteArrayInputStream input = new ByteArrayInputStream(Base64.decode(base64CRL)); return (java.security.cert.X509CRL) cf.generateCRL(input); }