/* * * Copyright (c) 2013 - 2020 Lijun Liao * * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.xipki.litecaclient; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLConnection; import java.nio.file.Files; import java.nio.file.StandardCopyOption; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.util.Objects; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.x509.Extension; /** * Utility class. * * @author Lijun Liao */ public class SdkUtil { private static CertificateFactory certFact; private static Object certFactLock = new Object(); private SdkUtil() { } public static X509Certificate parseCert(File file) throws IOException, CertificateException { requireNonNull("file", file); InputStream in = Files.newInputStream(file.toPath()); try { return parseCert(in); } finally { in.close(); } } // method parseCert public static X509Certificate parseCert(byte[] certBytes) throws CertificateException { requireNonNull("certBytes", certBytes); return parseCert(new ByteArrayInputStream(certBytes)); } public static X509Certificate parseCert(InputStream certStream) throws CertificateException { requireNonNull("certStream", certStream); X509Certificate cert = (X509Certificate) getCertFactory().generateCertificate(certStream); if (cert == null) { throw new CertificateEncodingException("the given one is not a valid X.509 certificate"); } return cert; } // method parseCert private static CertificateFactory getCertFactory() throws CertificateException { synchronized (certFactLock) { if (certFact == null) { certFact = CertificateFactory.getInstance("X.509"); } return certFact; } } // method getCertFactory public static byte[] extractSki(X509Certificate cert) throws CertificateEncodingException { byte[] fullExtValue = cert.getExtensionValue(Extension.subjectKeyIdentifier.getId()); if (fullExtValue == null) { return null; } byte[] extValue = ASN1OctetString.getInstance(fullExtValue).getOctets(); return ASN1OctetString.getInstance(extValue).getOctets(); } public static byte[] read(File file) throws IOException { return read(Files.newInputStream(file.toPath())); } public static byte[] read(InputStream in) throws IOException { try { ByteArrayOutputStream bout = new ByteArrayOutputStream(); int readed = 0; byte[] buffer = new byte[2048]; while ((readed = in.read(buffer)) != -1) { bout.write(buffer, 0, readed); } return bout.toByteArray(); } finally { try { in.close(); } catch (IOException ex) { // CHECKSTYLE:SKIP } } } // method read public static void save(File file, byte[] content) throws IOException { File parent = file.getParentFile(); if (parent != null && !parent.exists()) { parent.mkdirs(); } Files.copy( new ByteArrayInputStream(content), file.toPath(), StandardCopyOption.REPLACE_EXISTING); } public static HttpURLConnection openHttpConn(URL url) throws IOException { requireNonNull("url", url); URLConnection conn = url.openConnection(); if (conn instanceof HttpURLConnection) { return (HttpURLConnection) conn; } throw new IOException(url.toString() + " is not of protocol HTTP: " + url.getProtocol()); } public static <T> T requireNonNull(String objName, T obj) { return Objects.requireNonNull(obj, objName + " may not be null"); } public static String requireNonBlank(String objName, String obj) { Objects.requireNonNull(obj, objName + " may not be null"); if (obj.isEmpty()) { throw new IllegalArgumentException(objName + " may not be blank"); } return obj; } public static byte[] send(URL url, String httpMethod, byte[] request, String requestContentType, String expectedResponseContentType) throws IOException { HttpURLConnection httpUrlConnection = SdkUtil.openHttpConn(url); httpUrlConnection.setDoOutput(true); httpUrlConnection.setUseCaches(false); httpUrlConnection.setRequestMethod(httpMethod); if (requestContentType != null) { httpUrlConnection.setRequestProperty("Content-Type", requestContentType); } if (request != null) { httpUrlConnection.setRequestProperty("Content-Length", Integer.toString(request.length)); OutputStream outputstream = httpUrlConnection.getOutputStream(); outputstream.write(request); outputstream.flush(); } InputStream inputStream = httpUrlConnection.getInputStream(); if (httpUrlConnection.getResponseCode() != HttpURLConnection.HTTP_OK) { inputStream.close(); throw new IOException("bad response: " + httpUrlConnection.getResponseCode() + " " + httpUrlConnection.getResponseMessage()); } String responseContentType = httpUrlConnection.getContentType(); boolean isValidContentType = false; if (responseContentType != null) { if (responseContentType.equalsIgnoreCase(expectedResponseContentType)) { isValidContentType = true; } } if (!isValidContentType) { inputStream.close(); throw new IOException("bad response: mime type " + responseContentType + " not supported!"); } return SdkUtil.read(inputStream); } // method send }