⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 certificatemanager.java

📁 openfire 服务器源码下载
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/** * $RCSfile$ * $Revision: $ * $Date: $ * * Copyright (C) 2008 Jive Software. All rights reserved. * * This software is published under the terms of the GNU Public License (GPL), * a copy of which is included in this distribution, or a commercial license * agreement with Jive. */package org.jivesoftware.util;import org.bouncycastle.asn1.*;import org.bouncycastle.asn1.x509.GeneralName;import org.bouncycastle.asn1.x509.GeneralNames;import org.bouncycastle.asn1.x509.X509Extensions;import org.bouncycastle.asn1.x509.X509Name;import org.bouncycastle.jce.PKCS10CertificationRequest;import org.bouncycastle.jce.provider.BouncyCastleProvider;import org.bouncycastle.openssl.PEMReader;import org.bouncycastle.openssl.PasswordFinder;import org.bouncycastle.x509.X509V3CertificateGenerator;import java.io.*;import java.math.BigInteger;import java.security.*;import java.security.cert.Certificate;import java.security.cert.CertificateFactory;import java.security.cert.CertificateParsingException;import java.security.cert.X509Certificate;import java.util.*;import java.util.LinkedList;import java.util.concurrent.CopyOnWriteArrayList;import java.util.regex.Matcher;import java.util.regex.Pattern;/** * Utility class that provides similar functionality to the keytool tool. Generated certificates * conform to the XMPP spec where domains are kept in the subject alternative names extension. * * @author Gaston Dombiak */public class CertificateManager {    private static Pattern cnPattern = Pattern.compile("(?i)(cn=)([^,]*)");    private static Pattern valuesPattern = Pattern.compile("(?i)(=)([^,]*)");    private static Provider provider = new BouncyCastleProvider();    /**     * The maximum length of lines in certification requests     */    private static final int CERT_REQ_LINE_LENGTH = 76;    private static List<CertificateEventListener> listeners = new CopyOnWriteArrayList<CertificateEventListener>();        static {        // Add the BC provider to the list of security providers        Security.addProvider(provider);    }    /**     * Creates a new X509 certificate using the DSA algorithm. The new certificate together with its private     * key are stored in the specified key store. However, the key store is not saved to the disk. This means     * that it is up to the "caller" to save the key store to disk after new certificates have been added     * to the store.     *     * @param ksKeys    key store where the new certificate and private key are going to be stored.     * @param keyPassword password of the keystore.     * @param alias     name to use when storing the certificate in the key store.     * @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 to store in the subject alternative name extension.     * @return the new X509 V3 Certificate.     * @throws GeneralSecurityException     * @throws IOException     */    public static X509Certificate createDSACert(KeyStore ksKeys, String keyPassword, String alias, String issuerDN,                                                String subjectDN, String domain)            throws GeneralSecurityException, IOException {        // Generate public and private keys        KeyPair keyPair = generateKeyPair("DSA", 1024);        // Create X509 certificate with keys and specified domain        X509Certificate cert = createX509V3Certificate(keyPair, 60, issuerDN, subjectDN, domain, "SHA1withDSA");        // Store new certificate and private key in the keystore        ksKeys.setKeyEntry(alias, keyPair.getPrivate(), keyPassword.toCharArray(), new X509Certificate[]{cert});        // Notify listeners that a new certificate has been created        for (CertificateEventListener listener : listeners) {            try {                listener.certificateCreated(ksKeys, alias, cert);            }            catch (Exception e) {                Log.error(e);            }        }        // Return new certificate        return cert;    }    /**     * Creates a new X509 certificate using the RSA algorithm. The new certificate together with its private     * key are stored in the specified key store. However, the key store is not saved to the disk. This means     * that it is up to the "caller" to save the key store to disk after new certificates have been added     * to the store.     *     * @param ksKeys    key store where the new certificate and private key are going to be stored.     * @param keyPassword password of the keystore.     * @param alias     name to use when storing the certificate in the key store.     * @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 to store in the subject alternative name extension.     * @return the new X509 V3 Certificate.     * @throws GeneralSecurityException     * @throws IOException     */    public static X509Certificate createRSACert(KeyStore ksKeys, String keyPassword, String alias, String issuerDN,                                                String subjectDN, String domain)            throws GeneralSecurityException, IOException {        // Generate public and private keys        KeyPair keyPair = generateKeyPair("RSA", 1024);        // Create X509 certificate with keys and specified domain        X509Certificate cert = createX509V3Certificate(keyPair, 60, issuerDN, subjectDN, domain, "MD5withRSA");        // Store new certificate and private key in the keystore        ksKeys.setKeyEntry(alias, keyPair.getPrivate(), keyPassword.toCharArray(), new X509Certificate[]{cert});        // Notify listeners that a new certificate has been created        for (CertificateEventListener listener : listeners) {            try {                listener.certificateCreated(ksKeys, alias, cert);            }            catch (Exception e) {                Log.error(e);            }        }        // Return new certificate        return cert;    }    /**     * Deletes the specified certificate from the     *     * @param ksKeys    key store where the certificate is stored.     * @param alias     alias of the certificate to delete.     * @throws GeneralSecurityException     * @throws IOException     */    public static void deleteCertificate(KeyStore ksKeys, String alias) throws GeneralSecurityException, IOException {        ksKeys.deleteEntry(alias);        // Notify listeners that a new certificate has been created        for (CertificateEventListener listener : listeners) {            try {                listener.certificateDeleted(ksKeys, alias);            }            catch (Exception e) {                Log.error(e);            }        }    }    /**     * Returns the identities of the remote server as defined in the specified certificate. The     * identities are defined in the subjectDN of the certificate and it can also be defined in     * the subjectAltName extensions of type "xmpp". When the extension is being used then the     * identities defined in the extension are going to be returned. Otherwise, the value stored in     * the subjectDN is returned.     *     * @param x509Certificate the certificate the holds the identities of the remote server.     * @return the identities of the remote server as defined in the specified certificate.     */    public static List<String> getPeerIdentities(X509Certificate x509Certificate) {        // Look the identity in the subjectAltName extension if available        List<String> names = getSubjectAlternativeNames(x509Certificate);        if (names.isEmpty()) {            String name = x509Certificate.getSubjectDN().getName();            Matcher matcher = cnPattern.matcher(name);            if (matcher.find()) {                name = matcher.group(2);            }            // Create an array with the unique identity            names = new ArrayList<String>();            names.add(name);        }        return names;    }    /**     * Returns the JID representation of an XMPP entity contained as a SubjectAltName extension     * in the certificate. If none was found then return <tt>null</tt>.     *     * @param certificate the certificate presented by the remote entity.     * @return the JID representation of an XMPP entity contained as a SubjectAltName extension     *         in the certificate. If none was found then return <tt>null</tt>.     */    private static List<String> getSubjectAlternativeNames(X509Certificate certificate) {        List<String> identities = new ArrayList<String>();        try {            Collection<List<?>> altNames = certificate.getSubjectAlternativeNames();            // Check that the certificate includes the SubjectAltName extension            if (altNames == null) {                return Collections.emptyList();            }            // Use the type OtherName to search for the certified server name            for (List item : altNames) {                Integer type = (Integer) item.get(0);                if (type == 0) {                    // Type OtherName found so return the associated value                    try {                        // Value is encoded using ASN.1 so decode it to get the server's identity                        ASN1InputStream decoder = new ASN1InputStream((byte[]) item.toArray()[1]);                        DEREncodable encoded = decoder.readObject();                        encoded = ((DERSequence) encoded).getObjectAt(1);                        encoded = ((DERTaggedObject) encoded).getObject();                        encoded = ((DERTaggedObject) encoded).getObject();                        String identity = ((DERUTF8String) encoded).getString();                        if (!"".equals(identity)) {                            // Add the decoded server name to the list of identities                            identities.add(identity);                        }                    }                    catch (UnsupportedEncodingException e) {                        // Ignore                    }                    catch (IOException e) {                        // Ignore                    }                    catch (Exception e) {                        Log.error("CertificateManager: Error decoding subjectAltName", e);                    }                }                // Other types are not good for XMPP so ignore them                else if (Log.isDebugEnabled()) {                    Log.debug("CertificateManager: SubjectAltName of invalid type found: " + certificate.getSubjectDN());                }            }        }        catch (CertificateParsingException e) {            Log.error("CertificateManager: Error parsing SubjectAltName in certificate: " + certificate.getSubjectDN(), e);        }        return identities;    }    /**     * Returns true if an RSA certificate was found in the specified keystore for the specified domain.     *     * @param ksKeys the keystore that contains the certificates.     * @param domain domain of the server signed by the certificate.     * @return true if an RSA certificate was found in the specified keystore for the specified domain.     * @throws KeyStoreException     */    public static boolean isRSACertificate(KeyStore ksKeys, String domain) throws KeyStoreException {        return isCertificate(ksKeys, domain, "RSA");    }    /**     * Returns true if an DSA certificate was found in the specified keystore for the specified domain.     *     * @param ksKeys the keystore that contains the certificates.     * @param domain domain of the server signed by the certificate.     * @return true if an DSA certificate was found in the specified keystore for the specified domain.     * @throws KeyStoreException     */    public static boolean isDSACertificate(KeyStore ksKeys, String domain) throws KeyStoreException {        return isCertificate(ksKeys, domain, "DSA");    }    /**     * Returns true if the specified certificate is using the DSA algorithm. The DSA algorithm is not     * good for encryption but only for authentication. On the other hand, the RSA algorithm is good     * for encryption and authentication.     *     * @param certificate the certificate to analyze.     * @return true if the specified certificate is using the DSA algorithm.     * @throws KeyStoreException     */    public static boolean isDSACertificate(X509Certificate certificate) throws KeyStoreException {        return certificate.getPublicKey().getAlgorithm().equals("DSA");    }    /**     * Returns true if a certificate with the specifed configuration was found in the key store.     *     * @param ksKeys the keystore to use for searching the certificate.     * @param domain the domain present in the subjectAltName or "*" if anything is accepted.     * @param algorithm the DSA or RSA algorithm used by the certificate.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -