| 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
 | 
 | 
package sun.security.provider.certpath;  | 
 | 
 | 
 | 
import java.math.BigInteger;  | 
 | 
import java.util.Collection;  | 
 | 
import java.util.Date;  | 
 | 
import java.util.Set;  | 
 | 
import java.security.GeneralSecurityException;  | 
 | 
import java.security.KeyFactory;  | 
 | 
import java.security.PublicKey;  | 
 | 
import java.security.SignatureException;  | 
 | 
import java.security.cert.Certificate;  | 
 | 
import java.security.cert.CertificateExpiredException;  | 
 | 
import java.security.cert.CertificateNotYetValidException;  | 
 | 
import java.security.cert.CertPathValidatorException;  | 
 | 
import java.security.cert.CertPathValidatorException.BasicReason;  | 
 | 
import java.security.cert.X509Certificate;  | 
 | 
import java.security.cert.PKIXCertPathChecker;  | 
 | 
import java.security.cert.PKIXReason;  | 
 | 
import java.security.cert.TrustAnchor;  | 
 | 
import java.security.interfaces.DSAParams;  | 
 | 
import java.security.interfaces.DSAPublicKey;  | 
 | 
import java.security.spec.DSAPublicKeySpec;  | 
 | 
import javax.security.auth.x500.X500Principal;  | 
 | 
import sun.security.x509.X500Name;  | 
 | 
import sun.security.util.Debug;  | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
class BasicChecker extends PKIXCertPathChecker { | 
 | 
 | 
 | 
    private static final Debug debug = Debug.getInstance("certpath"); | 
 | 
    private final PublicKey trustedPubKey;  | 
 | 
    private final X500Principal caName;  | 
 | 
    private final Date date;  | 
 | 
    private final String sigProvider;  | 
 | 
    private final boolean sigOnly;  | 
 | 
    private X500Principal prevSubject;  | 
 | 
    private PublicKey prevPubKey;  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    BasicChecker(TrustAnchor anchor, Date date, String sigProvider,  | 
 | 
                 boolean sigOnly) { | 
 | 
        if (anchor.getTrustedCert() != null) { | 
 | 
            this.trustedPubKey = anchor.getTrustedCert().getPublicKey();  | 
 | 
            this.caName = anchor.getTrustedCert().getSubjectX500Principal();  | 
 | 
        } else { | 
 | 
            this.trustedPubKey = anchor.getCAPublicKey();  | 
 | 
            this.caName = anchor.getCA();  | 
 | 
        }  | 
 | 
        this.date = date;  | 
 | 
        this.sigProvider = sigProvider;  | 
 | 
        this.sigOnly = sigOnly;  | 
 | 
        this.prevPubKey = trustedPubKey;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    @Override  | 
 | 
    public void init(boolean forward) throws CertPathValidatorException { | 
 | 
        if (!forward) { | 
 | 
            prevPubKey = trustedPubKey;  | 
 | 
            if (PKIX.isDSAPublicKeyWithoutParams(prevPubKey)) { | 
 | 
                // If TrustAnchor is a DSA public key and it has no params, it  | 
 | 
                // cannot be used to verify the signature of the first cert,  | 
 | 
                  | 
 | 
                throw new CertPathValidatorException("Key parameters missing"); | 
 | 
            }  | 
 | 
            prevSubject = caName;  | 
 | 
        } else { | 
 | 
            throw new  | 
 | 
                CertPathValidatorException("forward checking not supported"); | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
    @Override  | 
 | 
    public boolean isForwardCheckingSupported() { | 
 | 
        return false;  | 
 | 
    }  | 
 | 
 | 
 | 
    @Override  | 
 | 
    public Set<String> getSupportedExtensions() { | 
 | 
        return null;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    @Override  | 
 | 
    public void check(Certificate cert, Collection<String> unresolvedCritExts)  | 
 | 
        throws CertPathValidatorException  | 
 | 
    { | 
 | 
        X509Certificate currCert = (X509Certificate)cert;  | 
 | 
 | 
 | 
        if (!sigOnly) { | 
 | 
            verifyValidity(currCert);  | 
 | 
            verifyNameChaining(currCert);  | 
 | 
        }  | 
 | 
        verifySignature(currCert);  | 
 | 
 | 
 | 
        updateState(currCert);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    private void verifySignature(X509Certificate cert)  | 
 | 
        throws CertPathValidatorException  | 
 | 
    { | 
 | 
        String msg = "signature";  | 
 | 
        if (debug != null)  | 
 | 
            debug.println("---checking " + msg + "..."); | 
 | 
 | 
 | 
        try { | 
 | 
            cert.verify(prevPubKey, sigProvider);  | 
 | 
        } catch (SignatureException e) { | 
 | 
            throw new CertPathValidatorException  | 
 | 
                (msg + " check failed", e, null, -1,  | 
 | 
                 BasicReason.INVALID_SIGNATURE);  | 
 | 
        } catch (GeneralSecurityException e) { | 
 | 
            throw new CertPathValidatorException(msg + " check failed", e);  | 
 | 
        }  | 
 | 
 | 
 | 
        if (debug != null)  | 
 | 
            debug.println(msg + " verified.");  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    private void verifyValidity(X509Certificate cert)  | 
 | 
        throws CertPathValidatorException  | 
 | 
    { | 
 | 
        String msg = "validity";  | 
 | 
        if (debug != null)  | 
 | 
            debug.println("---checking " + msg + ":" + date.toString() + "..."); | 
 | 
 | 
 | 
        try { | 
 | 
            cert.checkValidity(date);  | 
 | 
        } catch (CertificateExpiredException e) { | 
 | 
            throw new CertPathValidatorException  | 
 | 
                (msg + " check failed", e, null, -1, BasicReason.EXPIRED);  | 
 | 
        } catch (CertificateNotYetValidException e) { | 
 | 
            throw new CertPathValidatorException  | 
 | 
                (msg + " check failed", e, null, -1, BasicReason.NOT_YET_VALID);  | 
 | 
        }  | 
 | 
 | 
 | 
        if (debug != null)  | 
 | 
            debug.println(msg + " verified.");  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    private void verifyNameChaining(X509Certificate cert)  | 
 | 
        throws CertPathValidatorException  | 
 | 
    { | 
 | 
        if (prevSubject != null) { | 
 | 
 | 
 | 
            String msg = "subject/issuer name chaining";  | 
 | 
            if (debug != null)  | 
 | 
                debug.println("---checking " + msg + "..."); | 
 | 
 | 
 | 
            X500Principal currIssuer = cert.getIssuerX500Principal();  | 
 | 
 | 
 | 
              | 
 | 
            if (X500Name.asX500Name(currIssuer).isEmpty()) { | 
 | 
                throw new CertPathValidatorException  | 
 | 
                    (msg + " check failed: " +  | 
 | 
                     "empty/null issuer DN in certificate is invalid", null,  | 
 | 
                     null, -1, PKIXReason.NAME_CHAINING);  | 
 | 
            }  | 
 | 
 | 
 | 
            if (!(currIssuer.equals(prevSubject))) { | 
 | 
                throw new CertPathValidatorException  | 
 | 
                    (msg + " check failed", null, null, -1,  | 
 | 
                     PKIXReason.NAME_CHAINING);  | 
 | 
            }  | 
 | 
 | 
 | 
            if (debug != null)  | 
 | 
                debug.println(msg + " verified.");  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    private void updateState(X509Certificate currCert)  | 
 | 
        throws CertPathValidatorException  | 
 | 
    { | 
 | 
        PublicKey cKey = currCert.getPublicKey();  | 
 | 
        if (debug != null) { | 
 | 
            debug.println("BasicChecker.updateState issuer: " + | 
 | 
                currCert.getIssuerX500Principal().toString() + "; subject: " +  | 
 | 
                currCert.getSubjectX500Principal() + "; serial#: " +  | 
 | 
                currCert.getSerialNumber().toString());  | 
 | 
        }  | 
 | 
        if (PKIX.isDSAPublicKeyWithoutParams(cKey)) { | 
 | 
              | 
 | 
            cKey = makeInheritedParamsKey(cKey, prevPubKey);  | 
 | 
            if (debug != null) debug.println("BasicChecker.updateState Made " + | 
 | 
                                             "key with inherited params");  | 
 | 
        }  | 
 | 
        prevPubKey = cKey;  | 
 | 
        prevSubject = currCert.getSubjectX500Principal();  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    static PublicKey makeInheritedParamsKey(PublicKey keyValueKey,  | 
 | 
        PublicKey keyParamsKey) throws CertPathValidatorException  | 
 | 
    { | 
 | 
        if (!(keyValueKey instanceof DSAPublicKey) ||  | 
 | 
            !(keyParamsKey instanceof DSAPublicKey))  | 
 | 
            throw new CertPathValidatorException("Input key is not " + | 
 | 
                                                 "appropriate type for " +  | 
 | 
                                                 "inheriting parameters");  | 
 | 
        DSAParams params = ((DSAPublicKey)keyParamsKey).getParams();  | 
 | 
        if (params == null)  | 
 | 
            throw new CertPathValidatorException("Key parameters missing"); | 
 | 
        try { | 
 | 
            BigInteger y = ((DSAPublicKey)keyValueKey).getY();  | 
 | 
            KeyFactory kf = KeyFactory.getInstance("DSA"); | 
 | 
            DSAPublicKeySpec ks = new DSAPublicKeySpec(y,  | 
 | 
                                                       params.getP(),  | 
 | 
                                                       params.getQ(),  | 
 | 
                                                       params.getG());  | 
 | 
            return kf.generatePublic(ks);  | 
 | 
        } catch (GeneralSecurityException e) { | 
 | 
            throw new CertPathValidatorException("Unable to generate key with" + | 
 | 
                                                 " inherited parameters: " +  | 
 | 
                                                 e.getMessage(), e);  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    PublicKey getPublicKey() { | 
 | 
        return prevPubKey;  | 
 | 
    }  | 
 | 
}  |