/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.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.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Ola Bini <ola@ologix.com> * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.x509store; import java.security.cert.CertificateException; import java.util.ArrayList; import java.util.List; /** * c: X509_TRUST * * @author <a href="mailto:ola.bini@ki.se">Ola Bini</a> */ public class Trust { static interface Checker<T> extends Function3<T, X509AuxCertificate, Integer> {} public int trust; public int flags; private Checker<Trust> checkTrust; private String name; private String arg1; private Object arg2; private Trust() {} Trust(int trust, int flags, Checker<Trust> checkTrust, String n, String a1, Object a2) { this.trust = trust; this.flags = flags; this.checkTrust = checkTrust; this.name = n; this.arg1 = a1; this.arg2 = a2; } /** * c: X509_TRUST_set_default */ /* public static Checker setDefault(Checker<String> trust) { Checker old_trust = defaultTrust; defaultTrust = trust; return old_trust; } */ private final static List<Trust> trustable = new ArrayList<Trust>(); /** * c: X509_check_trust */ public static int checkTrust(X509AuxCertificate x, int id, int flags) throws Exception { if ( id == -1 ) return 1; int idx = getByID(id); if (idx == -1) { return defaultTrust.call(Integer.toString(id), x, Integer.valueOf(flags)); } Trust pt = getFirst(idx); return pt.checkTrust.call(pt, x, Integer.valueOf(flags)); } /** * c: X509_TRUST_get_count */ public static int getCount() { return trustable.size() + trstandard.length; } /** * c: X509_TRUST_get0 */ public static Trust getFirst(int idx) { if(idx < 0) { return null; } if(idx < trstandard.length) { return trstandard[idx]; } return trustable.get(idx - trstandard.length); } /** * c: X509_TRUST_get_by_id */ public static int getByID(int id) { if ( id >= X509Utils.X509_TRUST_MIN && id <= X509Utils.X509_TRUST_MAX ) { return id - X509Utils.X509_TRUST_MIN; } int i = 0; for ( Trust t : trustable ) { if(t.trust == id) { return i + trstandard.length; } } return -1; } /** * c: X509_TRUST_set */ public static int set(int[] t, int trust) { if(getByID(trust) == -1) { X509Error.addError(X509Utils.X509_R_INVALID_TRUST); return 0; } t[0] = trust; return 1; } /** * c: X509_TRUST_add */ static int add(int id, int flags, Checker<Trust> ck, String name, String arg1, Object arg2) { int idx; Trust trtmp; flags &= ~X509Utils.X509_TRUST_DYNAMIC; flags |= X509Utils.X509_TRUST_DYNAMIC_NAME; idx = getByID(id); if(idx == -1) { trtmp = new Trust(); trtmp.flags = X509Utils.X509_TRUST_DYNAMIC; } else { trtmp = getFirst(idx); } trtmp.name = name; trtmp.flags &= X509Utils.X509_TRUST_DYNAMIC; trtmp.flags |= flags; trtmp.trust = id; trtmp.checkTrust = ck; trtmp.arg1 = arg1; trtmp.arg2 = arg2; if(idx == -1) { trustable.add(trtmp); } return 1; } /** * c: X509_TRUST_cleanup */ public static void cleanup() { trustable.clear(); } /** * c: X509_TRUST_get_flags */ public int getFlags() { return flags; } /** * c: X509_TRUST_get0_name */ public String getName() { return name; } /** * c: X509_TRUST_get_trust */ public int getTrust() { return trust; } /** * c: trust_compat */ final static Checker<Trust> trustCompatibe = new Checker<Trust>() { public int call(final Trust trust, final X509AuxCertificate x, final Integer flags) throws CertificateException { Purpose.checkPurpose(x,-1,0); if ( x.getIssuerX500Principal().equals( x.getSubjectX500Principal() ) ) { // self signed return X509Utils.X509_TRUST_TRUSTED; } else { return X509Utils.X509_TRUST_UNTRUSTED; } } }; /** * c: trust_1oidany */ final static Checker<Trust> trust1OIDAny = new Checker<Trust>() { public int call(final Trust trust, final X509AuxCertificate x, final Integer flags) throws Exception { final X509Aux aux = x.aux; if ( aux != null && ( aux.trust.size() > 0 || aux.reject.size() > 0 ) ) { return objTrust.call(trust.arg1, x, flags); } return trustCompatibe.call(trust, x, flags); } }; /** * c: trust_1oid */ final static Checker<Trust> trust1OID = new Checker<Trust>() { public int call(final Trust trust, final X509AuxCertificate x, final Integer flags) throws Exception { if ( x.aux != null ) { return objTrust.call(trust.arg1, x, flags); } return X509Utils.X509_TRUST_UNTRUSTED; } }; /** * c: obj_trust */ final static Checker<String> objTrust = new Checker<String>() { public int call(final String id, final X509AuxCertificate x, final Integer flags) { final X509Aux aux = x.aux; if ( aux == null ) { return X509Utils.X509_TRUST_UNTRUSTED; } for ( String rejectId : aux.reject ) { if ( rejectId.equals(id) ) { return X509Utils.X509_TRUST_REJECTED; } } for ( String trustId : aux.trust ) { if ( trustId.equals(id) ) { return X509Utils.X509_TRUST_TRUSTED; } } return X509Utils.X509_TRUST_UNTRUSTED; } }; /** * c: default_trust */ static Checker<String> defaultTrust = objTrust; private final static Trust[] trstandard = new Trust[] { new Trust(X509Utils.X509_TRUST_COMPAT, 0, trustCompatibe, "compatible", null, null), new Trust(X509Utils.X509_TRUST_SSL_CLIENT, 0, trust1OIDAny, "SSL Client", "1.3.6.1.5.5.7.3.2", null), new Trust(X509Utils.X509_TRUST_SSL_SERVER, 0, trust1OIDAny, "SSL Server", "1.3.6.1.5.5.7.3.1", null), new Trust(X509Utils.X509_TRUST_EMAIL, 0, trust1OIDAny, "S/MIME email", "1.3.6.1.5.5.7.3.4", null), new Trust(X509Utils.X509_TRUST_OBJECT_SIGN, 0, trust1OIDAny, "Object Signer", "1.3.6.1.5.5.7.3.3", null), new Trust(X509Utils.X509_TRUST_OCSP_SIGN, 0, trust1OID, "OCSP responder", "1.3.6.1.5.5.7.3.9", null), new Trust(X509Utils.X509_TRUST_OCSP_REQUEST, 0, trust1OID, "OCSP request", "1.3.6.1.5.5.7.48.1", null), }; }// X509_TRUST