/* * 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 * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR APARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Copyright (C) 2017 Donovan Lampa <donovan.lampa@gmail.com> * Copyright (C) 2009-2017 The JRuby Team * * 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. * * * JRuby-OpenSSL includes software by The Legion of the Bouncy Castle Inc. * Please, visit (http://bouncycastle.org/license.html) for licensing details. */ package org.jruby.ext.openssl; import java.security.Security; import java.util.HashMap; import java.util.Map; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.jruby.Ruby; import org.jruby.RubyClass; import org.jruby.RubyFixnum; import org.jruby.RubyModule; import org.jruby.exceptions.RaiseException; import org.jruby.runtime.builtin.IRubyObject; /** * OCSP * * @author lampad */ public class OCSP { //Response has valid confirmations private static final String _RESPONSE_STATUS_SUCCESSFUL_STR = "RESPONSE_STATUS_SUCCESSFUL"; private static final int _RESPONSE_STATUS_SUCCESSFUL = 0; //Illegal confirmation request private static final String _RESPONSE_STATUS_MALFORMEDREQUEST_STR = "RESPONSE_STATUS_MALFORMEDREQUEST"; private static final int _RESPONSE_STATUS_MALFORMEDREQUEST = 1; //Internal error in issuer private static final String _RESPONSE_STATUS_INTERNALERROR_STR = "RESPONSE_STATUS_INTERNALERROR"; private static final int _RESPONSE_STATUS_INTERNALERROR = 2; //Try again later private static final String _RESPONSE_STATUS_TRYLATER_STR = "RESPONSE_STATUS_TRYLATER"; private static final int _RESPONSE_STATUS_TRYLATER = 3; //You must sign the request and resubmit private static final String _RESPONSE_STATUS_SIGREQUIRED_STR = "RESPONSE_STATUS_SIGREQUIRED"; private static final int _RESPONSE_STATUS_SIGREQUIRED = 5; //Your request is unauthorized. private static final String _RESPONSE_STATUS_UNAUTHORIZED_STR = "RESPONSE_STATUS_UNAUTHORIZED"; private static final int _RESPONSE_STATUS_UNAUTHORIZED = 6; private static final Map<Integer, String> responseMap; //The certificate was revoked for an unknown reason private static final int _REVOKED_STATUS_NOSTATUS = -1; //The certificate was revoked for an unspecified reason private static final int _REVOKED_STATUS_UNSPECIFIED = 0; //The certificate was revoked due to a key compromise private static final int _REVOKED_STATUS_KEYCOMPROMISE = 1; //This CA certificate was revoked due to a key compromise private static final int _REVOKED_STATUS_CACOMPROMISE = 2; //The certificate subject's name or other information changed private static final int _REVOKED_STATUS_AFFILIATIONCHANGED = 3; //The certificate was superseded by a new certificate private static final int _REVOKED_STATUS_SUPERSEDED = 4; //The certificate is no longer needed private static final int _REVOKED_STATUS_CESSATIONOFOPERATION = 5; //The certificate is on hold private static final int _REVOKED_STATUS_CERTIFICATEHOLD = 6; //The certificate was previously on hold and should now be removed from the CRL private static final int _REVOKED_STATUS_REMOVEFROMCRL = 8; //Do not include certificates in the response private static final int _NOCERTS = 0x1; //Do not search certificates contained in the response for a signer private static final int _NOINTERN = 0x2; //Do not check the signature on the response private static final int _NOSIGS = 0x4; //Do not verify the certificate chain on the response private static final int _NOCHAIN = 0x8; //Do not verify the response at all private static final int _NOVERIFY = 0x10; //Do not check trust private static final int _NOEXPLICIT = 0x20; //(This flag is not used by OpenSSL 1.0.1g) private static final int _NOCASIGN = 0x40; //(This flag is not used by OpenSSL 1.0.1g) private static final int _NODELEGATED = 0x80; //Do not make additional signing certificate checks private static final int _NOCHECKS = 0x100; //Do not verify additional certificates private static final int _TRUSTOTHER = 0x200; //Identify the response by signing the certificate key ID private static final int _RESPID_KEY = 0x400; //Do not include producedAt time in response private static final int _NOTIME = 0x800; /* * Indicates the certificate is not revoked but does not necessarily mean * the certificate was issued or that this response is within the * certificate's validity interval */ private static final int _V_CERTSTATUS_GOOD = 0; /* Indicates the certificate has been revoked either permanently or * temporarily (on hold). */ private static final int _V_CERTSTATUS_REVOKED = 1; /* Indicates the responder does not know about the certificate being * requested. */ private static final int _V_CERTSTATUS_UNKNOWN = 2; //The responder ID is based on the key name. private static final int _V_RESPID_NAME = 0; //The responder ID is based on the public key. private static final int _V_RESPID_KEY =1; static { Map<Integer, String> resMap = new HashMap<Integer, String>(); resMap.put(_RESPONSE_STATUS_SUCCESSFUL, _RESPONSE_STATUS_SUCCESSFUL_STR); resMap.put(_RESPONSE_STATUS_MALFORMEDREQUEST, _RESPONSE_STATUS_MALFORMEDREQUEST_STR); resMap.put(_RESPONSE_STATUS_INTERNALERROR, _RESPONSE_STATUS_INTERNALERROR_STR); resMap.put(_RESPONSE_STATUS_TRYLATER, _RESPONSE_STATUS_TRYLATER_STR); resMap.put(_RESPONSE_STATUS_SIGREQUIRED, _RESPONSE_STATUS_SIGREQUIRED_STR); resMap.put(_RESPONSE_STATUS_UNAUTHORIZED, _RESPONSE_STATUS_UNAUTHORIZED_STR); responseMap = resMap; } public static void createOCSP(final Ruby runtime, final RubyModule OpenSSL) { final RubyModule OCSP = OpenSSL.defineModuleUnder("OCSP"); final RubyClass OpenSSLError = OpenSSL.getClass("OpenSSLError"); Security.addProvider(new BouncyCastleProvider()); OCSP.defineClassUnder("OCSPError", OpenSSLError, OpenSSLError.getAllocator()); OCSPBasicResponse.createBasicResponse(runtime, OCSP); OCSPCertificateId.createCertificateId(runtime, OCSP); OCSPRequest.createRequest(runtime, OCSP); OCSPResponse.createResponse(runtime, OCSP); OCSPSingleResponse.createSingleResponse(runtime, OCSP); //ResponseStatuses OCSP.setConstant(_RESPONSE_STATUS_SUCCESSFUL_STR, runtime.newFixnum(_RESPONSE_STATUS_SUCCESSFUL)); OCSP.setConstant(_RESPONSE_STATUS_MALFORMEDREQUEST_STR, runtime.newFixnum(_RESPONSE_STATUS_MALFORMEDREQUEST)); OCSP.setConstant(_RESPONSE_STATUS_INTERNALERROR_STR, runtime.newFixnum(_RESPONSE_STATUS_INTERNALERROR)); OCSP.setConstant(_RESPONSE_STATUS_TRYLATER_STR, runtime.newFixnum(_RESPONSE_STATUS_TRYLATER)); OCSP.setConstant(_RESPONSE_STATUS_SIGREQUIRED_STR, runtime.newFixnum(_RESPONSE_STATUS_SIGREQUIRED)); OCSP.setConstant(_RESPONSE_STATUS_UNAUTHORIZED_STR, runtime.newFixnum(_RESPONSE_STATUS_UNAUTHORIZED)); //RevocationReasons OCSP.setConstant("REVOKED_STATUS_NOSTATUS", runtime.newFixnum(_REVOKED_STATUS_NOSTATUS)); OCSP.setConstant("REVOKED_STATUS_UNSPECIFIED", runtime.newFixnum(_REVOKED_STATUS_UNSPECIFIED)); OCSP.setConstant("REVOKED_STATUS_KEYCOMPROMISE", runtime.newFixnum(_REVOKED_STATUS_KEYCOMPROMISE)); OCSP.setConstant("REVOKED_STATUS_CACOMPROMISE", runtime.newFixnum(_REVOKED_STATUS_CACOMPROMISE)); OCSP.setConstant("REVOKED_STATUS_AFFILIATIONCHANGED", runtime.newFixnum(_REVOKED_STATUS_AFFILIATIONCHANGED)); OCSP.setConstant("REVOKED_STATUS_SUPERSEDED", runtime.newFixnum(_REVOKED_STATUS_SUPERSEDED)); OCSP.setConstant("REVOKED_STATUS_CESSATIONOFOPERATION", runtime.newFixnum(_REVOKED_STATUS_CESSATIONOFOPERATION)); OCSP.setConstant("REVOKED_STATUS_CERTIFICATEHOLD", runtime.newFixnum(_REVOKED_STATUS_CERTIFICATEHOLD)); OCSP.setConstant("REVOKED_STATUS_REMOVEFROMCRL", runtime.newFixnum(_REVOKED_STATUS_REMOVEFROMCRL)); OCSP.setConstant("NOCERTS", runtime.newFixnum(_NOCERTS)); OCSP.setConstant("NOINTERN", runtime.newFixnum(_NOINTERN)); OCSP.setConstant("NOSIGS", runtime.newFixnum(_NOSIGS)); OCSP.setConstant("NOCHAIN", runtime.newFixnum(_NOCHAIN)); OCSP.setConstant("NOVERIFY", runtime.newFixnum(_NOVERIFY)); OCSP.setConstant("NOEXPLICIT", runtime.newFixnum(_NOEXPLICIT)); OCSP.setConstant("NOCASIGN", runtime.newFixnum(_NOCASIGN)); OCSP.setConstant("NODELEGATED", runtime.newFixnum(_NODELEGATED)); OCSP.setConstant("NOCHECKS", runtime.newFixnum(_NOCHECKS)); OCSP.setConstant("TRUSTOTHER", runtime.newFixnum(_TRUSTOTHER)); OCSP.setConstant("RESPID_KEY", runtime.newFixnum(_RESPID_KEY)); OCSP.setConstant("NOTIME", runtime.newFixnum(_NOTIME)); OCSP.setConstant("V_CERTSTATUS_GOOD", runtime.newFixnum(_V_CERTSTATUS_GOOD)); OCSP.setConstant("V_CERTSTATUS_REVOKED", runtime.newFixnum(_V_CERTSTATUS_REVOKED)); OCSP.setConstant("V_CERTSTATUS_UNKNOWN", runtime.newFixnum(_V_CERTSTATUS_UNKNOWN)); OCSP.setConstant("V_RESPID_NAME", runtime.newFixnum(_V_RESPID_NAME)); OCSP.setConstant("V_RESPID_KEY", runtime.newFixnum(_V_RESPID_KEY)); } public static String getResponseStringForValue(IRubyObject fixnum) { RubyFixnum rubyFixnum = (RubyFixnum) fixnum; return responseMap.get((int)rubyFixnum.getLongValue()); } static RaiseException newOCSPError(Ruby runtime, Exception ex) { return Utils.newError(runtime, _OCSP(runtime).getClass("OCSPError"), ex); } static RubyModule _OCSP(final Ruby runtime) { return (RubyModule) runtime.getModule("OpenSSL").getConstant("OCSP"); } }