2 * ============LICENSE_START====================================================
4 * ===========================================================================
5 * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
6 * ===========================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END====================================================
22 package org.onap.aaf.cadi.http;
24 import java.io.ByteArrayInputStream;
25 import java.io.ByteArrayOutputStream;
26 import java.io.IOException;
27 import java.net.HttpURLConnection;
28 import java.security.PrivateKey;
29 import java.security.SecureRandom;
30 import java.security.Signature;
31 import java.security.cert.CertificateEncodingException;
32 import java.security.cert.X509Certificate;
34 import javax.net.ssl.HttpsURLConnection;
35 import javax.net.ssl.X509KeyManager;
37 import org.onap.aaf.cadi.CadiException;
38 import org.onap.aaf.cadi.SecuritySetter;
39 import org.onap.aaf.cadi.Symm;
40 import org.onap.aaf.cadi.client.AbsAuthentication;
41 import org.onap.aaf.cadi.config.Config;
42 import org.onap.aaf.cadi.config.SecurityInfoC;
43 import org.onap.aaf.misc.env.APIException;
44 import org.onap.aaf.misc.env.util.Chrono;
47 public class HX509SS implements SecuritySetter<HttpURLConnection> {
48 private static final byte[] X509 = "x509 ".getBytes();
49 private PrivateKey priv;
52 private SecurityInfoC<HttpURLConnection> securityInfo;
55 private static int count = new SecureRandom().nextInt();
57 public HX509SS(SecurityInfoC<HttpURLConnection> si) throws APIException, CadiException {
61 public HX509SS(SecurityInfoC<HttpURLConnection> si, boolean asDefault) throws APIException, CadiException {
62 this(null,si,asDefault);
65 public HX509SS(final String sendAlias, SecurityInfoC<HttpURLConnection> si) throws APIException, CadiException {
66 this(sendAlias, si, false);
69 public HX509SS(final String sendAlias, SecurityInfoC<HttpURLConnection> si, boolean asDefault) throws APIException, CadiException {
71 if((alias=sendAlias) == null) {
72 if(si.default_alias == null) {
73 throw new APIException("JKS Alias is required to use X509SS Security. Use " + Config.CADI_ALIAS +" to set default alias");
75 alias = si.default_alias;
80 X509KeyManager[] xkms = si.getKeyManagers();
81 if(xkms==null || xkms.length==0) {
82 throw new APIException("There are no valid keys available in given Keystores. Wrong Keypass? Expired?");
84 for(int i=0;priv==null&&i<xkms.length;++i) {
85 priv = xkms[i].getPrivateKey(alias);
88 for(int i=0;cert==null&&i<xkms.length;++i) {
89 X509Certificate[] chain = xkms[i].getCertificateChain(alias);
90 if(chain!=null&&chain.length>0) {
91 algo = chain[0].getSigAlgName();
92 pub = chain[0].getEncoded();
93 ByteArrayOutputStream baos = new ByteArrayOutputStream(pub.length*2);
94 ByteArrayInputStream bais = new ByteArrayInputStream(pub);
95 Symm.base64noSplit.encode(bais,baos,X509);
96 cert = baos.toString();
99 } catch (CertificateEncodingException | IOException e) {
100 throw new CadiException(e);
103 throw new APIException("X509 Security Setter not configured");
108 public void setSecurity(HttpURLConnection huc) throws CadiException {
109 if(huc instanceof HttpsURLConnection) {
110 securityInfo.setSocketFactoryOn((HttpsURLConnection)huc);
112 if(alias==null) { // must be a one-way
113 huc.setRequestProperty(AbsAuthentication.AUTHORIZATION, cert);
115 // Test Signed content
117 String data = "SignedContent["+ inc() + ']' + Chrono.dateTime();
118 huc.setRequestProperty("Data", data);
120 Signature sig = Signature.getInstance(algo);
122 sig.update(data.getBytes());
123 byte[] signature = sig.sign();
125 ByteArrayOutputStream baos = new ByteArrayOutputStream((int)(signature.length*1.3));
126 ByteArrayInputStream bais = new ByteArrayInputStream(signature);
127 Symm.base64noSplit.encode(bais, baos);
128 huc.setRequestProperty("Signature", new String(baos.toByteArray()));
130 } catch (Exception e) {
131 throw new CadiException(e);
136 private synchronized int inc() {
141 * @see org.onap.aaf.cadi.SecuritySetter#getID()
144 public String getID() {
149 public int setLastResponse(int respCode) {