📄 certificatemanager.java
字号:
if (!publickey.equals(publickey1)) { throw new Exception("Public keys in reply and keystore don't match"); } if (certReply.equals(certificate)) { throw new Exception("Certificate reply and certificate in keystore are identical"); } } Map<Principal, List<X509Certificate>> knownCerts = new Hashtable<Principal, List<X509Certificate>>(); if (keyStore.size() > 0) { knownCerts.putAll(getCertsByIssuer(keyStore)); } if (trustCACerts && trustStore.size() > 0) { knownCerts.putAll(getCertsByIssuer(trustStore)); } LinkedList<X509Certificate> answer = new LinkedList<X509Certificate>(); if (buildChain(certReply, answer, knownCerts)) { return answer; } else { throw new Exception("Failed to establish chain from reply"); } } /** * Builds the certificate chain of the specified certificate based on the known list of certificates * that were issued by their respective Principals. Returns true if the entire chain of all certificates * was successfully built. * * @param certificate certificate to build its chain. * @param answer the certificate chain for the corresponding certificate. * @param knownCerts list of known certificates grouped by their issues (i.e. Principals). * @return true if the entire chain of all certificates was successfully built. */ private static boolean buildChain(X509Certificate certificate, LinkedList<X509Certificate> answer, Map<Principal, List<X509Certificate>> knownCerts) { Principal subject = certificate.getSubjectDN(); Principal issuer = certificate.getIssuerDN(); // Check if the certificate is a root certificate (i.e. was issued by the same Principal that // is present in the subject) if (subject.equals(issuer)) { answer.addFirst(certificate); return true; } // Get the list of known certificates of the certificate's issuer List<X509Certificate> issuerCerts = knownCerts.get(issuer); if (issuerCerts == null || issuerCerts.isEmpty()) { // No certificates were found so building of chain failed return false; } for (X509Certificate issuerCert : issuerCerts) { PublicKey publickey = issuerCert.getPublicKey(); try { // Verify the certificate with the specified public key certificate.verify(publickey); // Certificate was verified successfully so build chain of issuer's certificate if (!buildChain(issuerCert, answer, knownCerts)) { return false; } } catch (Exception exception) { // Failed to verify certificate return false; } } answer.addFirst(certificate); return true; } /** * Returns a Map where the key holds the certificate issuers and values the certificates of each issuer. * * @param ks the keystore to get its certs per issuer. * @return a map with the certificates per issuer. * @throws Exception */ private static Map<Principal, List<X509Certificate>> getCertsByIssuer(KeyStore ks) throws Exception { Map<Principal, List<X509Certificate>> answer = new HashMap<Principal, List<X509Certificate>>(); Enumeration<String> aliases = ks.aliases(); while (aliases.hasMoreElements()) { String alias = aliases.nextElement(); X509Certificate cert = (X509Certificate) ks.getCertificate(alias); if (cert != null) { Principal subjectDN = cert.getSubjectDN(); List<X509Certificate> vec = answer.get(subjectDN); if (vec == null) { vec = new ArrayList<X509Certificate>(); vec.add(cert); } else { if (!vec.contains(cert)) { vec.add(cert); } } answer.put(subjectDN, vec); } } return answer; } /** * Validates chain in certification reply, and returns the ordered * elements of the chain (with user certificate first, and root * certificate last in the array). * * @param alias the alias name * @param userCert the user certificate of the alias * @param replyCerts the chain provided in the reply */ private static List<X509Certificate> validateReply(KeyStore keyStore, KeyStore trustStore, String alias, X509Certificate userCert, List<X509Certificate> replyCerts, boolean trustCACerts, boolean verifyRoot) throws Exception { // order the certs in the reply (bottom-up). int i; X509Certificate tmpCert; if (userCert != null) { PublicKey userPubKey = userCert.getPublicKey(); for (i = 0; i < replyCerts.size(); i++) { if (userPubKey.equals(replyCerts.get(i).getPublicKey())) { break; } } if (i == replyCerts.size()) { throw new Exception( "Certificate reply does not contain public key for <alias>: " + alias); } tmpCert = replyCerts.get(0); replyCerts.set(0, replyCerts.get(i)); replyCerts.set(i, tmpCert); } Principal issuer = replyCerts.get(0).getIssuerDN(); for (i = 1; i < replyCerts.size() - 1; i++) { // find a cert in the reply whose "subject" is the same as the // given "issuer" int j; for (j = i; j < replyCerts.size(); j++) { Principal subject = replyCerts.get(j).getSubjectDN(); if (subject.equals(issuer)) { tmpCert = replyCerts.get(i); replyCerts.set(i, replyCerts.get(j)); replyCerts.set(j, tmpCert); issuer = replyCerts.get(i).getIssuerDN(); break; } } if (j == replyCerts.size()) { throw new Exception("Incomplete certificate chain in reply"); } } // now verify each cert in the ordered chain for (i = 0; i < replyCerts.size() - 1; i++) { PublicKey pubKey = replyCerts.get(i + 1).getPublicKey(); try { replyCerts.get(i).verify(pubKey); } catch (Exception e) { throw new Exception( "Certificate chain in reply does not verify: " + e.getMessage()); } } if (!verifyRoot) { return replyCerts; } // do we trust the (root) cert at the top? X509Certificate topCert = replyCerts.get(replyCerts.size() - 1); boolean foundInKeyStore = keyStore.getCertificateAlias(topCert) != null; boolean foundInCAStore = trustCACerts && (trustStore.getCertificateAlias(topCert) != null); if (!foundInKeyStore && !foundInCAStore) { boolean verified = false; X509Certificate rootCert = null; if (trustCACerts) { for (Enumeration<String> aliases = trustStore.aliases(); aliases.hasMoreElements();) { String name = aliases.nextElement(); rootCert = (X509Certificate) trustStore.getCertificate(name); if (rootCert != null) { try { topCert.verify(rootCert.getPublicKey()); verified = true; break; } catch (Exception e) { // Ignore } } } } if (!verified) { return null; } else { // Check if the cert is a self-signed cert if (!topCert.getSubjectDN().equals(topCert.getIssuerDN())) { // append the (self-signed) root CA cert to the chain replyCerts.add(rootCert); } } } return replyCerts; } /** * Creates an X509 version3 certificate. * * @param kp KeyPair that keeps the public and private keys for the new certificate. * @param months time to live * @param issuerDN Issuer string e.g "O=Grid,OU=OGSA,CN=ACME" * @param subjectDN Subject string e.g "O=Grid,OU=OGSA,CN=John Doe" * @param domain Domain of the server. * @param signAlgoritm Signature algorithm. This can be either a name or an OID. * @return X509 V3 Certificate * @throws GeneralSecurityException * @throws IOException */ private static synchronized X509Certificate createX509V3Certificate(KeyPair kp, int months, String issuerDN, String subjectDN, String domain, String signAlgoritm) throws GeneralSecurityException, IOException { PublicKey pubKey = kp.getPublic(); PrivateKey privKey = kp.getPrivate(); byte[] serno = new byte[8]; SecureRandom random = SecureRandom.getInstance("SHA1PRNG"); random.setSeed((new Date().getTime())); random.nextBytes(serno); BigInteger serial = (new java.math.BigInteger(serno)).abs(); X509V3CertificateGenerator certGenerator = new X509V3CertificateGenerator(); certGenerator.reset(); certGenerator.setSerialNumber(serial); certGenerator.setIssuerDN(new X509Name(issuerDN)); certGenerator.setNotBefore(new Date(System.currentTimeMillis())); certGenerator.setNotAfter( new Date(System.currentTimeMillis() + months * (1000L * 60 * 60 * 24 * 30))); certGenerator.setSubjectDN(new X509Name(subjectDN)); certGenerator.setPublicKey(pubKey); certGenerator.setSignatureAlgorithm(signAlgoritm); // Generate the subject alternative name boolean critical = subjectDN == null || "".equals(subjectDN.trim()); DERSequence othernameSequence = new DERSequence(new ASN1Encodable[]{ new DERObjectIdentifier("1.3.6.1.5.5.7.8.5"), new DERTaggedObject(true, 0, new DERUTF8String(domain))}); GeneralName othernameGN = new GeneralName(GeneralName.otherName, othernameSequence); GeneralNames subjectAltNames = new GeneralNames(new DERSequence(new ASN1Encodable[]{othernameGN})); // Add subject alternative name extension certGenerator.addExtension(X509Extensions.SubjectAlternativeName, critical, subjectAltNames); X509Certificate cert = certGenerator.generateX509Certificate(privKey, "BC", new SecureRandom()); cert.checkValidity(new Date()); cert.verify(pubKey); return cert; } /** * Returns a new public & private key with the specified algorithm (e.g. DSA, RSA, etc.). * * @param algorithm DSA, RSA, etc. * @param keysize the keysize. This is an algorithm-specific metric, such as modulus * length, specified in number of bits. * @return a new public & private key with the specified algorithm (e.g. DSA, RSA, etc.). * @throws GeneralSecurityException */ private static KeyPair generateKeyPair(String algorithm, int keysize) throws GeneralSecurityException { KeyPairGenerator generator; if (provider == null) { generator = KeyPairGenerator.getInstance(algorithm); } else { generator = KeyPairGenerator.getInstance(algorithm, provider); } generator.initialize(keysize, new SecureRandom()); return generator.generateKeyPair(); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -