f441186e6c0db44d51eb411c649c75326e1f8edd
[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 }