org.jruby.ext.openssl.x509store.Purpose Maven / Gradle / Ivy
/***** BEGIN LICENSE BLOCK *****
* Version: CPL 1.0/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Common 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/cpl-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
*
* 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 CPL, 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 CPL, the GPL or the LGPL.
***** END LICENSE BLOCK *****/
package org.jruby.ext.openssl.x509store;
import java.util.ArrayList;
import java.util.List;
/**
* c: X509_PURPOSE
*
* @author Ola Bini
*/
public class Purpose {
private static final String XKU_EMAIL_PROTECT = "1.3.6.1.5.5.7.3.4"; // Email protection
private static final String XKU_SSL_CLIENT = "1.3.6.1.5.5.7.3.2"; // SSL Client Authentication
private static final String[] XKU_SSL_SERVER = new String[]{
"1.3.6.1.5.5.7.3.1", // SSL Server Authentication
"2.16.840.1.113730.4.1", // Netscape Server Gated Crypto
"1.3.6.1.4.1.311.10.3.3" // Microsoft Server Gated Crypto
};
public static interface CheckPurposeFunction extends Function3 {
public static final CheckPurposeFunction EMPTY = new CheckPurposeFunction(){
public int call(Object arg0, Object arg1, Object arg2) {
return -1;
}
};
}
public int purpose;
public int trust; /* Default trust ID */
public int flags;
public CheckPurposeFunction checkPurpose;
public String name;
public String sname;
public Object userData;
public Purpose() {}
public Purpose(int p, int t, int f, CheckPurposeFunction cp, String n, String s, Object u) {
this.purpose = p; this.trust = t;
this.flags = f; this.checkPurpose = cp;
this.name = n; this.sname = s;
this.userData = u;
}
/**
* c: X509_check_purpose
*/
public static int checkPurpose(X509AuxCertificate x, int id, int ca) throws Exception {
if(id == -1) {
return 1;
}
int idx = getByID(id);
if(idx == -1) {
return -1;
}
Purpose pt = getFirst(idx);
return pt.checkPurpose.call(pt,x,new Integer(ca));
}
/**
* c: X509_PURPOSE_set
*/
public static int set(int[] p, int purpose) {
if(getByID(purpose) == -1) {
X509Error.addError(X509Utils.X509V3_R_INVALID_PURPOSE);
return 0;
}
p[0] = purpose;
return 1;
}
private final static List xptable = new ArrayList();
/**
* c: X509_PURPOSE_get_count
*/
public static int getCount() {
return xptable.size() + xstandard.length;
}
/**
* c: X509_PURPOSE_get0
*/
public static Purpose getFirst(int idx) {
if(idx < 0) {
return null;
}
if(idx < xstandard.length) {
return xstandard[idx];
}
return xptable.get(idx - xstandard.length);
}
/**
* c: X509_PURPOSE_get_by_sname
*/
public static int getBySName(String sname) {
for(int i=0;i= X509Utils.X509_PURPOSE_MIN && (purpose <= X509Utils.X509_PURPOSE_MAX)) {
return purpose - X509Utils.X509_PURPOSE_MIN;
}
int i = 0;
for(Purpose p : xptable) {
if(p.purpose == purpose) {
return i + xstandard.length;
}
}
return -1;
}
/**
* c: X509_PURPOSE_add
*/
public static int add(int id, int trust, int flags, CheckPurposeFunction ck, String name, String sname, Object arg) {
flags &= ~X509Utils.X509_PURPOSE_DYNAMIC;
flags |= X509Utils.X509_PURPOSE_DYNAMIC_NAME;
int idx = getByID(id);
Purpose ptmp;
if(idx == -1) {
ptmp = new Purpose();
ptmp.flags = X509Utils.X509_PURPOSE_DYNAMIC;
} else {
ptmp = getFirst(idx);
}
ptmp.name = name;
ptmp.sname = sname;
ptmp.flags &= X509Utils.X509_PURPOSE_DYNAMIC;
ptmp.flags |= flags;
ptmp.purpose = id;
ptmp.trust = trust;
ptmp.checkPurpose = ck;
ptmp.userData = arg;
if(idx == -1) {
xptable.add(ptmp);
}
return 1;
}
/**
* c: X509_PURPOSE_cleanup
*/
public static void cleanup() {
xptable.clear();
}
/**
* c: X509_PURPOSE_get_id
*/
public int getID() {
return purpose;
}
/**
* c: X509_PURPOSE_get0_name
*/
public String getName() {
return name;
}
/**
* c: X509_PURPOSE_get0_sname
*/
public String getSName() {
return sname;
}
/**
* c: X509_PURPOSE_get_trust
*/
public int getTrust() {
return trust;
}
/**
* c: X509_check_ca
*/
public static int checkCA(X509AuxCertificate x) throws Exception {
if(x.getKeyUsage() != null && !x.getKeyUsage()[5]) { // KEY_CERT_SIGN
return 0;
}
if(x.getExtensionValue("2.5.29.19") != null) { // BASIC_CONSTRAINTS
if(x.getBasicConstraints() != -1) { // is CA.
return 1;
} else {
return 0;
}
} else {
if(x.getVersion() == 1 && x.getIssuerX500Principal().equals(x.getSubjectX500Principal())) { // V1_ROOT
return 3;
}
if(x.getKeyUsage() != null) {
return 4;
}
Integer nsCertType = x.getNsCertType();
if (nsCertType != null && (nsCertType & X509Utils.NS_ANY_CA) != 0) {
return 5;
}
return 0;
}
}
/**
* c: check_ssl_ca
*/
public static int checkSSLCA(X509AuxCertificate x) throws Exception {
int ca_ret = checkCA(x);
if(ca_ret == 0) {
return 0;
}
Integer nsCertType = x.getNsCertType();
boolean v2 = nsCertType != null && (nsCertType & X509Utils.NS_SSL_CA) != 0;
if(ca_ret != 5 || v2) {
return ca_ret;
}
return 0;
}
/**
* c: xku_reject: check if the cert must be rejected(true) or not
*/
public static boolean xkuReject(X509AuxCertificate x, String mustHaveXku) throws Exception {
List xku = x.getExtendedKeyUsage();
return (xku != null) && !xku.contains(mustHaveXku);
}
public static boolean xkuReject(X509AuxCertificate x, String[] mustHaveOneOfXku) throws Exception {
List xku = x.getExtendedKeyUsage();
if(xku == null) {
return false;
}
for (String mustHaveXku : mustHaveOneOfXku) {
if(xku.contains(mustHaveXku)) {
return false;
}
}
return true;
}
/**
* c: ns_reject
*/
public static boolean nsReject(X509AuxCertificate x, int mustHaveCertType) throws Exception {
Integer nsCertType = x.getNsCertType();
return (nsCertType != null) && (nsCertType & mustHaveCertType) == 0;
}
/**
* c: purpose_smime
*/
public static int purposeSMIME(X509AuxCertificate x, int ca) throws Exception {
if(xkuReject(x,XKU_EMAIL_PROTECT)) {
return 0; // must allow email protection
}
if(ca != 0) {
int ca_ret = checkCA(x);
if(ca_ret == 0) {
return 0;
}
Integer nsCertType = x.getNsCertType();
boolean v2 = nsCertType != null && (nsCertType & X509Utils.NS_SMIME_CA) != 0;
if(ca_ret != 5 || v2) {
return ca_ret;
} else {
return 0;
}
}
Integer nsCertType = x.getNsCertType();
if (nsCertType != null) {
if ((nsCertType & X509Utils.NS_SMIME) != 0) {
return 1;
}
if ((nsCertType & X509Utils.NS_SSL_CLIENT) != 0) {
return 2;
}
return 0;
}
return 1;
}
/**
* c: check_purpose_ssl_client
*/
public final static CheckPurposeFunction checkPurposeSSLClient = new CheckPurposeFunction() {
public int call(Object _xp, Object _x, Object _ca) throws Exception {
X509AuxCertificate x = (X509AuxCertificate)_x;
if(xkuReject(x, XKU_SSL_CLIENT)) {
return 0;
}
int ca = ((Integer)_ca).intValue();
if(ca != 0) {
return checkSSLCA(x);
}
if(x.getKeyUsage() != null && !x.getKeyUsage()[0]) {
return 0;
}
if(nsReject(x, X509Utils.NS_SSL_CLIENT)) {
// when the cert has nsCertType, it must include NS_SSL_CLIENT
return 0;
}
return 1;
}
};
/**
* c: check_purpose_ssl_server
*/
public final static CheckPurposeFunction checkPurposeSSLServer = new CheckPurposeFunction() {
public int call(Object _xp, Object _x, Object _ca) throws Exception {
X509AuxCertificate x = (X509AuxCertificate)_x;
int ca = ((Integer)_ca).intValue();
if(xkuReject(x, XKU_SSL_SERVER)) {
return 0;
}
if(ca != 0) {
return checkSSLCA(x);
}
if(nsReject(x, X509Utils.NS_SSL_SERVER)) {
// when the cert has nsCertType, it must include NS_SSL_SERVER
return 0;
}
/* Now as for keyUsage: we'll at least need to sign OR encipher */
if(x.getKeyUsage() != null && !(x.getKeyUsage()[0] || x.getKeyUsage()[2])) {
return 0;
}
return 1;
}
};
/**
* c: check_purpose_ns_ssl_server
*/
public final static CheckPurposeFunction checkPurposeNSSSLServer = new CheckPurposeFunction() {
public int call(Object _xp, Object _x, Object _ca) throws Exception {
Purpose xp = (Purpose)_xp;
X509AuxCertificate x = (X509AuxCertificate)_x;
int ca = ((Integer)_ca).intValue();
int ret = checkPurposeSSLServer.call(xp,x,_ca);
if(ret == 0 || ca != 0) {
return ret;
}
if(x.getKeyUsage() != null && !x.getKeyUsage()[2]) {
return 0;
}
return 1;
}
};
/**
* c: check_purpose_smime_sign
*/
public final static CheckPurposeFunction checkPurposeSMIMESign = new CheckPurposeFunction() {
public int call(Object _xp, Object _x, Object _ca) throws Exception {
X509AuxCertificate x = (X509AuxCertificate)_x;
int ca = ((Integer)_ca).intValue();
int ret = purposeSMIME(x,ca);
if(ret == 0 || ca != 0) {
return ret;
}
if(x.getKeyUsage() != null && (!x.getKeyUsage()[0] || !x.getKeyUsage()[1])) {
return 0;
}
return ret;
}
};
/**
* c: check_purpose_smime_encrypt
*/
public final static CheckPurposeFunction checkPurposeSMIMEEncrypt = new CheckPurposeFunction() {
public int call(Object _xp, Object _x, Object _ca) throws Exception {
X509AuxCertificate x = (X509AuxCertificate)_x;
int ca = ((Integer)_ca).intValue();
int ret = purposeSMIME(x,ca);
if(ret == 0 || ca != 0) {
return ret;
}
if(x.getKeyUsage() != null && !x.getKeyUsage()[2]) {
return 0;
}
return ret;
}
};
/**
* c: check_purpose_crl_sign
*/
public final static CheckPurposeFunction checkPurposeCRLSign = new CheckPurposeFunction() {
public int call(Object _xp, Object _x, Object _ca) throws Exception {
X509AuxCertificate x = (X509AuxCertificate)_x;
int ca = ((Integer)_ca).intValue();
if(ca != 0) {
int ca_ret = checkCA(x);
if(ca_ret != 2) {
return ca_ret;
}
return 0;
}
if(x.getKeyUsage() != null && !x.getKeyUsage()[6]) {
return 0;
}
return 1;
}
};
/**
* c: no_check
*/
public final static CheckPurposeFunction noCheck = new CheckPurposeFunction() {
public int call(Object _xp, Object _x, Object _ca) {
return 1;
}
};
/**
* c: ocsp_helper
*/
public final static CheckPurposeFunction oscpHelper = new CheckPurposeFunction() {
public int call(Object _xp, Object _x, Object _ca) throws Exception {
if(((Integer)_ca).intValue() != 0) {
return checkCA((X509AuxCertificate)_x);
}
return 1;
}
};
public final static Purpose[] xstandard = new Purpose[] {
new Purpose(X509Utils.X509_PURPOSE_SSL_CLIENT, X509Utils.X509_TRUST_SSL_CLIENT, 0, checkPurposeSSLClient, "SSL client", "sslclient", null),
new Purpose(X509Utils.X509_PURPOSE_SSL_SERVER, X509Utils.X509_TRUST_SSL_SERVER, 0, checkPurposeSSLServer, "SSL server", "sslserver", null),
new Purpose(X509Utils.X509_PURPOSE_NS_SSL_SERVER, X509Utils.X509_TRUST_SSL_SERVER, 0, checkPurposeNSSSLServer, "Netscape SSL server", "nssslserver", null),
new Purpose(X509Utils.X509_PURPOSE_SMIME_SIGN, X509Utils.X509_TRUST_EMAIL, 0, checkPurposeSMIMESign, "S/MIME signing", "smimesign", null),
new Purpose(X509Utils.X509_PURPOSE_SMIME_ENCRYPT, X509Utils.X509_TRUST_EMAIL, 0, checkPurposeSMIMEEncrypt, "S/MIME encryption", "smimeencrypt", null),
new Purpose(X509Utils.X509_PURPOSE_CRL_SIGN, X509Utils.X509_TRUST_COMPAT, 0, checkPurposeCRLSign, "CRL signing", "crlsign", null),
new Purpose(X509Utils.X509_PURPOSE_ANY, X509Utils.X509_TRUST_DEFAULT, 0, noCheck, "Any Purpose", "any", null),
new Purpose(X509Utils.X509_PURPOSE_OCSP_HELPER, X509Utils.X509_TRUST_COMPAT, 0, oscpHelper, "OCSP helper", "ocsphelper", null),
};
}// X509_PURPOSE
© 2015 - 2025 Weber Informatics LLC | Privacy Policy