/** * Copyright (c) Istituto Nazionale di Fisica Nucleare, 2006-2014. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.italiangrid.voms.ac.impl; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.List; import org.bouncycastle.asn1.x509.AttributeCertificate; import org.italiangrid.voms.VOMSAttribute; import org.italiangrid.voms.ac.VOMSACLookupStrategy; import org.italiangrid.voms.ac.VOMSACValidationStrategy; import org.italiangrid.voms.ac.VOMSACValidator; import org.italiangrid.voms.ac.VOMSValidationResult; import org.italiangrid.voms.ac.ValidationResultListener; import org.italiangrid.voms.asn1.VOMSACUtils; import org.italiangrid.voms.store.UpdatingVOMSTrustStore; import org.italiangrid.voms.store.VOMSTrustStore; import org.italiangrid.voms.store.VOMSTrustStores; import org.italiangrid.voms.util.CertificateValidatorBuilder; import org.italiangrid.voms.util.NullListener; import eu.emi.security.authn.x509.X509CertChainValidatorExt; /** * The default implementation of the VOMS validator. * * @author andreaceccanti * */ public class DefaultVOMSValidator extends DefaultVOMSACParser implements VOMSACValidator { public static final String DEFAULT_TRUST_ANCHORS_DIR = "/etc/grid-security/certificates"; private final VOMSACValidationStrategy validationStrategy; private final VOMSTrustStore trustStore; private ValidationResultListener validationResultListener; private final Object listenerLock = new Object(); public static class Builder { private VOMSACValidationStrategy validationStrategy; private VOMSTrustStore trustStore; private ValidationResultListener validationResultListener; private X509CertChainValidatorExt certChainValidator; private VOMSACLookupStrategy acLookupStrategy; public Builder() { } public Builder validationStrategy(VOMSACValidationStrategy s) { this.validationStrategy = s; return this; } public Builder trustStore(VOMSTrustStore ts) { this.trustStore = ts; return this; } public Builder validationListener(ValidationResultListener l) { this.validationResultListener = l; return this; } public Builder certChainValidator(X509CertChainValidatorExt v) { this.certChainValidator = v; return this; } public Builder acLookupStrategy(VOMSACLookupStrategy ls) { this.acLookupStrategy = ls; return this; } private void sanityChecks() { if (validationStrategy == null) { if (trustStore == null) trustStore = VOMSTrustStores.newTrustStore(); if (certChainValidator == null) certChainValidator = new CertificateValidatorBuilder() .trustAnchorsDir(DEFAULT_TRUST_ANCHORS_DIR).build(); validationStrategy = new DefaultVOMSValidationStrategy(trustStore, certChainValidator); } if (validationResultListener == null) validationResultListener = NullListener.INSTANCE; if (acLookupStrategy == null) acLookupStrategy = new LeafACLookupStrategy(); } public DefaultVOMSValidator build() { sanityChecks(); return new DefaultVOMSValidator(this); } } private DefaultVOMSValidator(Builder b) { super(b.acLookupStrategy); this.validationStrategy = b.validationStrategy; this.trustStore = b.trustStore; this.validationResultListener = b.validationResultListener; } public List<VOMSValidationResult> validateWithResult( X509Certificate[] validatedChain) { return internalValidate(validatedChain); } protected List<VOMSValidationResult> internalValidate( X509Certificate[] validatedChain) { List<VOMSAttribute> parsedAttrs = parse(validatedChain); List<VOMSValidationResult> results = new ArrayList<VOMSValidationResult>(); for (VOMSAttribute a : parsedAttrs) { VOMSValidationResult result = validationStrategy.validateAC(a, validatedChain); synchronized (listenerLock) { validationResultListener.notifyValidationResult(result); } results.add(result); } return results; } public List<VOMSAttribute> validate(X509Certificate[] validatedChain) { List<VOMSAttribute> validAttributes = new ArrayList<VOMSAttribute>(); for (VOMSValidationResult result : internalValidate(validatedChain)) { if (result.isValid()) validAttributes.add(result.getAttributes()); } return validAttributes; } public void shutdown() { if (trustStore instanceof UpdatingVOMSTrustStore) ((UpdatingVOMSTrustStore) trustStore).cancel(); } public List<AttributeCertificate> validateACs(List<AttributeCertificate> acs) { List<AttributeCertificate> validatedAcs = new ArrayList<AttributeCertificate>(); for (AttributeCertificate ac : acs) { VOMSAttribute vomsAttrs = VOMSACUtils.deserializeVOMSAttributes(ac); VOMSValidationResult result = validationStrategy.validateAC(vomsAttrs); synchronized (listenerLock) { validationResultListener.notifyValidationResult(result); } if (result.isValid()) validatedAcs.add(ac); } return validatedAcs; } public void setValidationResultListener(ValidationResultListener listener) { synchronized (listenerLock) { if (listener != null) this.validationResultListener = listener; } } }