c9ff59dbbc344d209d90e9818f49284fa2b6daba
[aaf/authz.git] / cadi / client / src / main / java / org / onap / aaf / cadi / http / HX509SS.java
1 /**
2  * ============LICENSE_START====================================================
3  * org.onap.aaf
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
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
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====================================================
19  *
20  */
21
22 package org.onap.aaf.cadi.http;
23
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;
33
34 import javax.net.ssl.HttpsURLConnection;
35 import javax.net.ssl.X509KeyManager;
36
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;
45
46
47 public class HX509SS implements SecuritySetter<HttpURLConnection> {
48         private static final byte[] X509 = "x509 ".getBytes();
49         private PrivateKey priv;
50         private byte[] pub;
51         private String cert;
52         private SecurityInfoC<HttpURLConnection> securityInfo;
53         private String algo;
54         private String alias;
55         private static int count = new SecureRandom().nextInt();
56
57         public HX509SS(SecurityInfoC<HttpURLConnection> si) throws APIException, CadiException {
58                 this(null,si,false);
59         }
60         
61         public HX509SS(SecurityInfoC<HttpURLConnection> si, boolean asDefault) throws APIException, CadiException {
62                 this(null,si,asDefault);
63         }
64         
65         public HX509SS(final String sendAlias, SecurityInfoC<HttpURLConnection> si) throws APIException, CadiException {
66                 this(sendAlias, si, false);
67         }
68
69         public HX509SS(final String sendAlias, SecurityInfoC<HttpURLConnection> si, boolean asDefault) throws APIException, CadiException {
70                 securityInfo = si;
71                 if((alias=sendAlias) == null) {
72                         if(si.defaultAlias == null) {
73                                 throw new APIException("JKS Alias is required to use X509SS Security.  Use " + Config.CADI_ALIAS +" to set default alias");
74                         } else {
75                                 alias = si.defaultAlias;
76                         }
77                 }
78                 
79                 priv=null;
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?");
83                 }
84                 for(int i=0;priv==null&&i<xkms.length;++i) {
85                         priv = xkms[i].getPrivateKey(alias);
86                 }
87                 try {
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();
97                                 }
98                         }
99                 } catch (CertificateEncodingException | IOException e) {
100                         throw new CadiException(e);
101                 }
102                 if(algo==null) {
103                         throw new APIException("X509 Security Setter not configured");
104                 }
105         }
106
107         @Override
108         public void setSecurity(HttpURLConnection huc) throws CadiException {
109                 if(huc instanceof HttpsURLConnection) {
110                         securityInfo.setSocketFactoryOn((HttpsURLConnection)huc);
111                 }
112                 if(alias==null) { // must be a one-way
113                         huc.setRequestProperty(AbsAuthentication.AUTHORIZATION, cert);
114                         
115                         // Test Signed content
116                         try {
117                                 String data = "SignedContent["+ inc() + ']' + Chrono.dateTime();
118                                 huc.setRequestProperty("Data", data);
119                                 
120                                 Signature sig = Signature.getInstance(algo);
121                                 sig.initSign(priv);
122                                 sig.update(data.getBytes());
123                                 byte[] signature = sig.sign();
124                                 
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()));
129                                 
130                         } catch (Exception e) {
131                                 throw new CadiException(e);
132                         }
133                 }
134         }
135         
136         private synchronized int inc() {
137                 return ++count;
138         }
139         
140         /* (non-Javadoc)
141          * @see org.onap.aaf.cadi.SecuritySetter#getID()
142          */
143         @Override
144         public String getID() {
145                 return alias;
146         }
147         
148         @Override
149         public int setLastResponse(int respCode) {
150                 return 0;
151         }
152 }