OpenSSLX509CRLEntry.java revision 4c87dc62be38bf5b5378c494a225316cb3101f2c
16e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/*
26e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) * Copyright (C) 2013 The Android Open Source Project
36e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) *
46e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) * Licensed under the Apache License, Version 2.0 (the "License");
56e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) * you may not use this file except in compliance with the License.
66e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) * You may obtain a copy of the License at
76e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) *
86e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) *      http://www.apache.org/licenses/LICENSE-2.0
96e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) *
106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) * Unless required by applicable law or agreed to in writing, software
116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) * distributed under the License is distributed on an "AS IS" BASIS,
126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) * See the License for the specific language governing permissions and
146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) * limitations under the License.
156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) */
166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)package org.apache.harmony.xnet.provider.jsse;
186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)import java.io.ByteArrayOutputStream;
206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)import java.math.BigInteger;
216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)import java.security.cert.CRLException;
226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)import java.security.cert.X509CRLEntry;
236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)import java.util.Arrays;
246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)import java.util.Calendar;
256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)import java.util.Date;
266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)import java.util.HashSet;
276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)import java.util.Set;
286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)import java.util.TimeZone;
296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)public class OpenSSLX509CRLEntry extends X509CRLEntry {
316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    private final long mContext;
326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    OpenSSLX509CRLEntry(long ctx) {
346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        mContext = ctx;
356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    }
366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    @Override
386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    public Set<String> getCriticalExtensionOIDs() {
396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        String[] critOids =
406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                NativeCrypto.get_X509_REVOKED_ext_oids(mContext,
416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                        NativeCrypto.EXTENSION_TYPE_CRITICAL);
426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        /*
446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)         * This API has a special case that if there are no extensions, we
456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)         * should return null. So if we have no critical extensions, we'll check
466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)         * non-critical extensions.
476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)         */
486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        if ((critOids.length == 0)
496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                && (NativeCrypto.get_X509_REVOKED_ext_oids(mContext,
506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                        NativeCrypto.EXTENSION_TYPE_NON_CRITICAL).length == 0)) {
516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            return null;
526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        }
536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        return new HashSet<String>(Arrays.asList(critOids));
556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    }
566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    @Override
586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    public byte[] getExtensionValue(String oid) {
596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        return NativeCrypto.X509_REVOKED_get_ext_oid(mContext, oid);
606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    }
616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    @Override
636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    public Set<String> getNonCriticalExtensionOIDs() {
646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        String[] critOids =
656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                NativeCrypto.get_X509_REVOKED_ext_oids(mContext,
666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                        NativeCrypto.EXTENSION_TYPE_NON_CRITICAL);
676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        /*
696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)         * This API has a special case that if there are no extensions, we
706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)         * should return null. So if we have no non-critical extensions, we'll
716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)         * check critical extensions.
726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)         */
736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        if ((critOids.length == 0)
746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                && (NativeCrypto.get_X509_REVOKED_ext_oids(mContext,
756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                        NativeCrypto.EXTENSION_TYPE_CRITICAL).length == 0)) {
766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            return null;
776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        }
786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        return new HashSet<String>(Arrays.asList(critOids));
806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    }
816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    @Override
836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    public boolean hasUnsupportedCriticalExtension() {
846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        final String[] criticalOids =
856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                NativeCrypto.get_X509_REVOKED_ext_oids(mContext,
866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                        NativeCrypto.EXTENSION_TYPE_CRITICAL);
876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        for (String oid : criticalOids) {
886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            final long extensionRef = NativeCrypto.X509_REVOKED_get_ext(mContext, oid);
896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            if (NativeCrypto.X509_supported_extension(extensionRef) != 1) {
906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                return true;
916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            }
926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        }
936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        return false;
956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    }
966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    @Override
986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    public byte[] getEncoded() throws CRLException {
996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        return NativeCrypto.i2d_X509_REVOKED(mContext);
1006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    }
1016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    @Override
1036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    public BigInteger getSerialNumber() {
1046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        return new BigInteger(NativeCrypto.X509_REVOKED_get_serialNumber(mContext));
1056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    }
1066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    @Override
1086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    public Date getRevocationDate() {
1096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
1106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        calendar.set(Calendar.MILLISECOND, 0);
1116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        NativeCrypto.ASN1_TIME_to_Calendar(NativeCrypto.get_X509_REVOKED_revocationDate(mContext),
1126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                calendar);
1136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        return calendar.getTime();
1146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    }
1156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    @Override
1176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    public boolean hasExtensions() {
1186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        return (NativeCrypto.get_X509_REVOKED_ext_oids(mContext,
1196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                NativeCrypto.EXTENSION_TYPE_NON_CRITICAL).length != 0)
1206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                || (NativeCrypto.get_X509_REVOKED_ext_oids(mContext,
1216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                        NativeCrypto.EXTENSION_TYPE_CRITICAL).length != 0);
1226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    }
1236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    @Override
1256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    public String toString() {
1266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        ByteArrayOutputStream os = new ByteArrayOutputStream();
1276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        long bioCtx = NativeCrypto.create_BIO_OutputStream(os);
1286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        try {
1296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            NativeCrypto.X509_REVOKED_print(bioCtx, mContext);
1306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            return os.toString();
1316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        } finally {
1326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            NativeCrypto.BIO_free(bioCtx);
1336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        }
1346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    }
1356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
1366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)