[AAF-21] Initial code import
[aaf/cadi.git] / client / src / main / java / com / att / cadi / http / HX509SS.java
1 /*******************************************************************************\r
2  * ============LICENSE_START====================================================\r
3  * * org.onap.aai\r
4  * * ===========================================================================\r
5  * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.\r
6  * * Copyright © 2017 Amdocs\r
7  * * ===========================================================================\r
8  * * Licensed under the Apache License, Version 2.0 (the "License");\r
9  * * you may not use this file except in compliance with the License.\r
10  * * You may obtain a copy of the License at\r
11  * * \r
12  *  *      http://www.apache.org/licenses/LICENSE-2.0\r
13  * * \r
14  *  * Unless required by applicable law or agreed to in writing, software\r
15  * * distributed under the License is distributed on an "AS IS" BASIS,\r
16  * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
17  * * See the License for the specific language governing permissions and\r
18  * * limitations under the License.\r
19  * * ============LICENSE_END====================================================\r
20  * *\r
21  * * ECOMP is a trademark and service mark of AT&T Intellectual Property.\r
22  * *\r
23  ******************************************************************************/\r
24 package com.att.cadi.http;\r
25 \r
26 import java.io.ByteArrayInputStream;\r
27 import java.io.ByteArrayOutputStream;\r
28 import java.io.IOException;\r
29 import java.net.HttpURLConnection;\r
30 import java.security.PrivateKey;\r
31 import java.security.SecureRandom;\r
32 import java.security.Signature;\r
33 import java.security.cert.CertificateEncodingException;\r
34 import java.security.cert.X509Certificate;\r
35 \r
36 import javax.net.ssl.HttpsURLConnection;\r
37 import javax.net.ssl.X509KeyManager;\r
38 \r
39 import com.att.cadi.CadiException;\r
40 import com.att.cadi.SecuritySetter;\r
41 import com.att.cadi.Symm;\r
42 import com.att.cadi.config.Config;\r
43 import com.att.cadi.config.SecurityInfoC;\r
44 import com.att.inno.env.APIException;\r
45 import com.att.inno.env.util.Chrono;\r
46 \r
47 \r
48 public class HX509SS implements SecuritySetter<HttpURLConnection> {\r
49         private static final byte[] X509 = "x509 ".getBytes();\r
50         private PrivateKey priv;\r
51         private byte[] pub;\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
57 \r
58         public HX509SS(SecurityInfoC<HttpURLConnection> si) throws APIException, IOException, CertificateEncodingException {\r
59                 this(null,si,false);\r
60         }\r
61         \r
62         public HX509SS(SecurityInfoC<HttpURLConnection> si, boolean asDefault) throws APIException, IOException, CertificateEncodingException {\r
63                 this(null,si,asDefault);\r
64         }\r
65         \r
66         public HX509SS(final String sendAlias, SecurityInfoC<HttpURLConnection> si) throws APIException, IOException, CertificateEncodingException {\r
67                 this(sendAlias, si, false);\r
68         }\r
69 \r
70         public HX509SS(final String sendAlias, SecurityInfoC<HttpURLConnection> si, boolean asDefault) throws APIException, IOException, CertificateEncodingException {\r
71                 securityInfo = si;\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
75                         } else {\r
76                                 alias = si.default_alias;\r
77                         }\r
78                 }\r
79                 \r
80                 priv=null;\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
84                 }\r
85                 for(int i=0;priv==null&&i<xkms.length;++i) {\r
86                         priv = xkms[i].getPrivateKey(alias);\r
87                 }\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
97                                 \r
98                                 /*\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
107                                 try {\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
114                                 }\r
115                                 */\r
116                         }\r
117                 }\r
118                 if(algo==null) {\r
119                         throw new APIException("X509 Security Setter not configured");\r
120                 }\r
121         }\r
122 \r
123         @Override\r
124         public void setSecurity(HttpURLConnection huc) throws CadiException {\r
125                 if(huc instanceof HttpsURLConnection) {\r
126                         securityInfo.setSocketFactoryOn((HttpsURLConnection)huc);\r
127                 }\r
128                 if(alias==null) { // must be a one-way\r
129                         huc.setRequestProperty("Authorization", cert);\r
130                         \r
131                         // Test Signed content\r
132                         try {\r
133                                 String data = "SignedContent["+ inc() + ']' + Chrono.dateTime();\r
134                                 huc.setRequestProperty("Data", data);\r
135                                 \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
140                                 \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
145                                 \r
146                         } catch (Exception e) {\r
147                                 throw new CadiException(e);\r
148                         }\r
149                 }\r
150         }\r
151         \r
152         private synchronized int inc() {\r
153                 return ++count;\r
154         }\r
155         \r
156         /* (non-Javadoc)\r
157          * @see com.att.cadi.SecuritySetter#getID()\r
158          */\r
159         @Override\r
160         public String getID() {\r
161                 return alias;\r
162         }\r
163         \r
164         @Override\r
165         public int setLastResponse(int respCode) {\r
166                 return 0;\r
167         }\r
168 }\r