001/*
002 * oauth2-oidc-sdk
003 *
004 * Copyright 2012-2016, Connect2id Ltd and contributors.
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use
007 * this file except in compliance with the License. You may obtain a copy of the
008 * License at
009 *
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software distributed
013 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
014 * CONDITIONS OF ANY KIND, either express or implied. See the License for the
015 * specific language governing permissions and limitations under the License.
016 */
017
018package com.nimbusds.oauth2.sdk.util;
019
020
021import java.security.Principal;
022import java.security.PublicKey;
023import java.security.cert.X509Certificate;
024
025
026/**
027 * X.509 certificate utilities.
028 */
029public class X509CertificateUtils {
030        
031        
032        /**
033         * Checks if the issuer DN and the subject DN of the specified X.509
034         * certificate match. The matched DNs are not normalised.
035         *
036         * @param cert The X.509 certificate. Must not be {@code null}.
037         *
038         * @return {@code true} if the issuer DN and and subject DN match, else
039         *         {@code false}.
040         */
041        public static boolean hasMatchingIssuerAndSubject(final X509Certificate cert) {
042                
043                Principal issuer = cert.getIssuerDN();
044                Principal subject = cert.getSubjectDN();
045                
046                return issuer != null && subject != null && issuer.equals(subject);
047        }
048        
049        
050        /**
051         * Checks if the specified X.509 certificate is self-issued, i.e. it
052         * has a matching issuer and subject, and the public key can be used to
053         * successfully validate the certificate's digital signature.
054         *
055         * @param cert The X.509 certificate. Must not be {@code null}.
056         *
057         * @return {@code true} if the X.509 certificate is self-issued, else
058         *         {@code false}.
059         */
060        public static boolean isSelfIssued(final X509Certificate cert) {
061                
062                return hasMatchingIssuerAndSubject(cert) && isSelfSigned(cert);
063        }
064        
065        
066        /**
067         * Checks if the specified X.509 certificate is self-signed, i.e. the
068         * public key can be used to successfully validate the certificate's
069         * digital signature.
070         *
071         * @param cert The X.509 certificate. Must not be {@code null}.
072         *
073         * @return {@code true} if the X.509 certificate is self-signed, else
074         *         {@code false}.
075         */
076        public static boolean isSelfSigned(final X509Certificate cert) {
077                
078                PublicKey publicKey = cert.getPublicKey();
079                
080                return hasValidSignature(cert, publicKey);
081        }
082        
083        
084        /**
085         * Validates the signature of a X.509 certificate with the specified
086         * public key. Intended for validating self-signed X.509 certificates
087         * with a pre-registered RSA or EC public key.
088         *
089         * @param cert   The X.509 certificate. Must not be {@code null}.
090         * @param pubKey The public key to use for the validation. Must not be
091         *               {@code null}.
092         *
093         * @return {@code true} if the signature is valid, else {@code false}.
094         */
095        public static boolean hasValidSignature(final X509Certificate cert,
096                                                final PublicKey pubKey) {
097                
098                try {
099                        cert.verify(pubKey);
100                } catch (Exception e) {
101                        return false;
102                }
103                
104                return true;
105        }
106}