1 /*******************************************************************************
\r
2 * ============LICENSE_START====================================================
\r
4 * * ===========================================================================
\r
5 * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
\r
6 * * ===========================================================================
\r
7 * * Licensed under the Apache License, Version 2.0 (the "License");
\r
8 * * you may not use this file except in compliance with the License.
\r
9 * * You may obtain a copy of the License at
\r
11 * * http://www.apache.org/licenses/LICENSE-2.0
\r
13 * * Unless required by applicable law or agreed to in writing, software
\r
14 * * distributed under the License is distributed on an "AS IS" BASIS,
\r
15 * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
16 * * See the License for the specific language governing permissions and
\r
17 * * limitations under the License.
\r
18 * * ============LICENSE_END====================================================
\r
20 * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
\r
22 ******************************************************************************/
\r
23 package org.onap.aaf.cadi.http;
\r
25 import java.io.ByteArrayInputStream;
\r
26 import java.io.ByteArrayOutputStream;
\r
27 import java.io.IOException;
\r
28 import java.net.HttpURLConnection;
\r
29 import java.security.PrivateKey;
\r
30 import java.security.SecureRandom;
\r
31 import java.security.Signature;
\r
32 import java.security.cert.CertificateEncodingException;
\r
33 import java.security.cert.X509Certificate;
\r
35 import javax.net.ssl.HttpsURLConnection;
\r
36 import javax.net.ssl.X509KeyManager;
\r
38 import org.onap.aaf.cadi.CadiException;
\r
39 import org.onap.aaf.cadi.SecuritySetter;
\r
40 import org.onap.aaf.cadi.Symm;
\r
41 import org.onap.aaf.cadi.config.Config;
\r
42 import org.onap.aaf.cadi.config.SecurityInfoC;
\r
44 import org.onap.aaf.inno.env.APIException;
\r
45 import org.onap.aaf.inno.env.util.Chrono;
\r
48 public class HX509SS implements SecuritySetter<HttpURLConnection> {
\r
49 private static final byte[] X509 = "x509 ".getBytes();
\r
50 private PrivateKey priv;
\r
52 private String cert;
\r
53 private SecurityInfoC<HttpURLConnection> securityInfo;
\r
54 private String algo;
\r
55 private String alias;
\r
56 private static int count = new SecureRandom().nextInt();
\r
58 public HX509SS(SecurityInfoC<HttpURLConnection> si) throws APIException, IOException, CertificateEncodingException {
\r
59 this(null,si,false);
\r
62 public HX509SS(SecurityInfoC<HttpURLConnection> si, boolean asDefault) throws APIException, IOException, CertificateEncodingException {
\r
63 this(null,si,asDefault);
\r
66 public HX509SS(final String sendAlias, SecurityInfoC<HttpURLConnection> si) throws APIException, IOException, CertificateEncodingException {
\r
67 this(sendAlias, si, false);
\r
70 public HX509SS(final String sendAlias, SecurityInfoC<HttpURLConnection> si, boolean asDefault) throws APIException, IOException, CertificateEncodingException {
\r
72 if((alias=sendAlias) == null) {
\r
73 if(si.default_alias == null) {
\r
74 throw new APIException("JKS Alias is required to use X509SS Security. Use " + Config.CADI_ALIAS +" to set default alias");
\r
76 alias = si.default_alias;
\r
81 X509KeyManager[] xkms = si.getKeyManagers();
\r
82 if(xkms==null || xkms.length==0) {
\r
83 throw new APIException("There are no valid keys available in given Keystores. Wrong Keypass? Expired?");
\r
85 for(int i=0;priv==null&&i<xkms.length;++i) {
\r
86 priv = xkms[i].getPrivateKey(alias);
\r
88 for(int i=0;cert==null&&i<xkms.length;++i) {
\r
89 X509Certificate[] chain = xkms[i].getCertificateChain(alias);
\r
90 if(chain!=null&&chain.length>0) {
\r
91 algo = chain[0].getSigAlgName();
\r
92 pub = chain[0].getEncoded();
\r
93 ByteArrayOutputStream baos = new ByteArrayOutputStream(pub.length*2);
\r
94 ByteArrayInputStream bais = new ByteArrayInputStream(pub);
\r
95 Symm.base64noSplit.encode(bais,baos,X509);
\r
96 cert = baos.toString();
\r
99 // Inner Test code, uncomment if fix needed
\r
100 bais = new ByteArrayInputStream(baos.toByteArray());
\r
101 baos = new ByteArrayOutputStream(input.length*2);
\r
102 Symm.base64noSplit().decode(bais,baos,5);
\r
103 byte[] output = baos.toByteArray();
\r
104 String reconstitute = output.toString();
\r
105 System.out.println("ok");
\r
106 CertificateFactory certFactory;
\r
108 bais = new ByteArrayInputStream(output);
\r
109 certFactory = CertificateFactory.getInstance("X.509");
\r
110 X509Certificate x509 = (X509Certificate)certFactory.generateCertificate(bais);
\r
111 System.out.println(x509.toString());
\r
112 } catch (CertificateException e) {
\r
113 e.printStackTrace();
\r
119 throw new APIException("X509 Security Setter not configured");
\r
124 public void setSecurity(HttpURLConnection huc) throws CadiException {
\r
125 if(huc instanceof HttpsURLConnection) {
\r
126 securityInfo.setSocketFactoryOn((HttpsURLConnection)huc);
\r
128 if(alias==null) { // must be a one-way
\r
129 huc.setRequestProperty("Authorization", cert);
\r
131 // Test Signed content
\r
133 String data = "SignedContent["+ inc() + ']' + Chrono.dateTime();
\r
134 huc.setRequestProperty("Data", data);
\r
136 Signature sig = Signature.getInstance(algo);
\r
137 sig.initSign(priv);
\r
138 sig.update(data.getBytes());
\r
139 byte[] signature = sig.sign();
\r
141 ByteArrayOutputStream baos = new ByteArrayOutputStream((int)(signature.length*1.3));
\r
142 ByteArrayInputStream bais = new ByteArrayInputStream(signature);
\r
143 Symm.base64noSplit.encode(bais, baos);
\r
144 huc.setRequestProperty("Signature", new String(baos.toByteArray()));
\r
146 } catch (Exception e) {
\r
147 throw new CadiException(e);
\r
152 private synchronized int inc() {
\r
157 * @see com.att.cadi.SecuritySetter#getID()
\r
160 public String getID() {
\r
165 public int setLastResponse(int respCode) {
\r