/***** 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