b790eded6a080db677b12b58633ad3e9aa8b29c6
[aaf/cadi.git] / client / src / main / java / com / att / cadi / http / HX509SS.java
1 /*******************************************************************************\r
2  * ============LICENSE_START====================================================\r
3  * * org.onap.aaf\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
10  * * \r
11  *  *      http://www.apache.org/licenses/LICENSE-2.0\r
12  * * \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
19  * *\r
20  * * ECOMP is a trademark and service mark of AT&T Intellectual Property.\r
21  * *\r
22  ******************************************************************************/\r
23 package com.att.cadi.http;\r
24 \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
34 \r
35 import javax.net.ssl.HttpsURLConnection;\r
36 import javax.net.ssl.X509KeyManager;\r
37 \r
38 import com.att.cadi.CadiException;\r
39 import com.att.cadi.SecuritySetter;\r
40 import com.att.cadi.Symm;\r
41 import com.att.cadi.config.Config;\r
42 import com.att.cadi.config.SecurityInfoC;\r
43 import com.att.inno.env.APIException;\r
44 import com.att.inno.env.util.Chrono;\r
45 \r
46 \r
47 public class HX509SS implements SecuritySetter<HttpURLConnection> {\r
48         private static final byte[] X509 = "x509 ".getBytes();\r
49         private PrivateKey priv;\r
50         private byte[] pub;\r
51         private String cert;\r
52         private SecurityInfoC<HttpURLConnection> securityInfo;\r
53         private String algo;\r
54         private String alias;\r
55         private static int count = new SecureRandom().nextInt();\r
56 \r
57         public HX509SS(SecurityInfoC<HttpURLConnection> si) throws APIException, IOException, CertificateEncodingException {\r
58                 this(null,si,false);\r
59         }\r
60         \r
61         public HX509SS(SecurityInfoC<HttpURLConnection> si, boolean asDefault) throws APIException, IOException, CertificateEncodingException {\r
62                 this(null,si,asDefault);\r
63         }\r
64         \r
65         public HX509SS(final String sendAlias, SecurityInfoC<HttpURLConnection> si) throws APIException, IOException, CertificateEncodingException {\r
66                 this(sendAlias, si, false);\r
67         }\r
68 \r
69         public HX509SS(final String sendAlias, SecurityInfoC<HttpURLConnection> si, boolean asDefault) throws APIException, IOException, CertificateEncodingException {\r
70                 securityInfo = si;\r
71                 if((alias=sendAlias) == null) {\r
72                         if(si.default_alias == null) {\r
73                                 throw new APIException("JKS Alias is required to use X509SS Security.  Use " + Config.CADI_ALIAS +" to set default alias");\r
74                         } else {\r
75                                 alias = si.default_alias;\r
76                         }\r
77                 }\r
78                 \r
79                 priv=null;\r
80                 X509KeyManager[] xkms = si.getKeyManagers();\r
81                 if(xkms==null || xkms.length==0) {\r
82                         throw new APIException("There are no valid keys available in given Keystores.  Wrong Keypass?  Expired?");\r
83                 }\r
84                 for(int i=0;priv==null&&i<xkms.length;++i) {\r
85                         priv = xkms[i].getPrivateKey(alias);\r
86                 }\r
87                 for(int i=0;cert==null&&i<xkms.length;++i) {\r
88                         X509Certificate[] chain = xkms[i].getCertificateChain(alias);\r
89                         if(chain!=null&&chain.length>0) {\r
90                                 algo = chain[0].getSigAlgName(); \r
91                                 pub = chain[0].getEncoded();\r
92                                 ByteArrayOutputStream baos = new ByteArrayOutputStream(pub.length*2); \r
93                                 ByteArrayInputStream bais = new ByteArrayInputStream(pub);\r
94                                 Symm.base64noSplit.encode(bais,baos,X509);\r
95                                 cert = baos.toString();\r
96                                 \r
97                                 /*\r
98                                 // Inner Test code, uncomment if fix needed\r
99                                 bais = new ByteArrayInputStream(baos.toByteArray());\r
100                                 baos = new ByteArrayOutputStream(input.length*2);\r
101                                 Symm.base64noSplit().decode(bais,baos,5);\r
102                                 byte[] output = baos.toByteArray();\r
103                                 String reconstitute = output.toString();\r
104                                 System.out.println("ok");\r
105                                 CertificateFactory certFactory;\r
106                                 try {\r
107                                         bais = new ByteArrayInputStream(output);\r
108                                         certFactory = CertificateFactory.getInstance("X.509");\r
109                                         X509Certificate x509 = (X509Certificate)certFactory.generateCertificate(bais);\r
110                                         System.out.println(x509.toString());\r
111                                 } catch (CertificateException e) {\r
112                                         e.printStackTrace();\r
113                                 }\r
114                                 */\r
115                         }\r
116                 }\r
117                 if(algo==null) {\r
118                         throw new APIException("X509 Security Setter not configured");\r
119                 }\r
120         }\r
121 \r
122         @Override\r
123         public void setSecurity(HttpURLConnection huc) throws CadiException {\r
124                 if(huc instanceof HttpsURLConnection) {\r
125                         securityInfo.setSocketFactoryOn((HttpsURLConnection)huc);\r
126                 }\r
127                 if(alias==null) { // must be a one-way\r
128                         huc.setRequestProperty("Authorization", cert);\r
129                         \r
130                         // Test Signed content\r
131                         try {\r
132                                 String data = "SignedContent["+ inc() + ']' + Chrono.dateTime();\r
133                                 huc.setRequestProperty("Data", data);\r
134                                 \r
135                                 Signature sig = Signature.getInstance(algo);\r
136                                 sig.initSign(priv);\r
137                                 sig.update(data.getBytes());\r
138                                 byte[] signature = sig.sign();\r
139                                 \r
140                                 ByteArrayOutputStream baos = new ByteArrayOutputStream((int)(signature.length*1.3));\r
141                                 ByteArrayInputStream bais = new ByteArrayInputStream(signature);\r
142                                 Symm.base64noSplit.encode(bais, baos);\r
143                                 huc.setRequestProperty("Signature", new String(baos.toByteArray()));\r
144                                 \r
145                         } catch (Exception e) {\r
146                                 throw new CadiException(e);\r
147                         }\r
148                 }\r
149         }\r
150         \r
151         private synchronized int inc() {\r
152                 return ++count;\r
153         }\r
154         \r
155         /* (non-Javadoc)\r
156          * @see com.att.cadi.SecuritySetter#getID()\r
157          */\r
158         @Override\r
159         public String getID() {\r
160                 return alias;\r
161         }\r
162         \r
163         @Override\r
164         public int setLastResponse(int respCode) {\r
165                 return 0;\r
166         }\r
167 }\r