// 
// Decompiled by Procyon v0.6.0
// 

package org.bouncycastle.cert.path.validations;

import org.bouncycastle.util.Memoable;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.util.Integers;
import org.bouncycastle.asn1.x509.BasicConstraints;
import org.bouncycastle.cert.path.CertPathValidationException;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.path.CertPathValidationContext;
import org.bouncycastle.cert.path.CertPathValidation;

public class BasicConstraintsValidation implements CertPathValidation
{
    private boolean previousCertWasCA;
    private Integer maxPathLength;
    private boolean isMandatory;
    
    public BasicConstraintsValidation() {
        this(true);
    }
    
    public BasicConstraintsValidation(final boolean isMandatory) {
        this.previousCertWasCA = true;
        this.maxPathLength = null;
        this.isMandatory = true;
        this.isMandatory = isMandatory;
    }
    
    @Override
    public void validate(final CertPathValidationContext certPathValidationContext, final X509CertificateHolder x509CertificateHolder) throws CertPathValidationException {
        certPathValidationContext.addHandledExtension(Extension.basicConstraints);
        if (!this.previousCertWasCA) {
            throw new CertPathValidationException("Basic constraints violated: issuer is not a CA");
        }
        final BasicConstraints fromExtensions = BasicConstraints.fromExtensions(x509CertificateHolder.getExtensions());
        this.previousCertWasCA = ((fromExtensions != null && fromExtensions.isCA()) || (fromExtensions == null && !this.isMandatory));
        if (this.maxPathLength != null && !x509CertificateHolder.getSubject().equals(x509CertificateHolder.getIssuer())) {
            if (this.maxPathLength < 0) {
                throw new CertPathValidationException("Basic constraints violated: path length exceeded");
            }
            this.maxPathLength = Integers.valueOf(this.maxPathLength - 1);
        }
        if (fromExtensions != null && fromExtensions.isCA()) {
            final ASN1Integer pathLenConstraintInteger = fromExtensions.getPathLenConstraintInteger();
            if (pathLenConstraintInteger != null) {
                final int intPositiveValueExact = pathLenConstraintInteger.intPositiveValueExact();
                if (this.maxPathLength == null || intPositiveValueExact < this.maxPathLength) {
                    this.maxPathLength = Integers.valueOf(intPositiveValueExact);
                }
            }
        }
    }
    
    @Override
    public Memoable copy() {
        final BasicConstraintsValidation basicConstraintsValidation = new BasicConstraintsValidation();
        basicConstraintsValidation.isMandatory = this.isMandatory;
        basicConstraintsValidation.previousCertWasCA = this.previousCertWasCA;
        basicConstraintsValidation.maxPathLength = this.maxPathLength;
        return basicConstraintsValidation;
    }
    
    @Override
    public void reset(final Memoable memoable) {
        final BasicConstraintsValidation basicConstraintsValidation = (BasicConstraintsValidation)memoable;
        this.isMandatory = basicConstraintsValidation.isMandatory;
        this.previousCertWasCA = basicConstraintsValidation.previousCertWasCA;
        this.maxPathLength = basicConstraintsValidation.maxPathLength;
    }
}
