Assign image keyname and pubkey at vnf level
[ccsdk/apps.git] / sdnr / wireless-transport / code-Carbon-SR1 / apps / devicemanager / impl / src / main / java / org / opendaylight / mwtn / base / http / BaseHTTPClient.java
1 package org.opendaylight.mwtn.base.http;
2
3 import java.io.ByteArrayInputStream;
4 import java.io.File;
5 import java.io.FileInputStream;
6 import java.io.FileNotFoundException;
7 import java.io.IOException;
8 import java.io.InputStream;
9 import java.io.OutputStream;
10 import java.net.HttpURLConnection;
11 import java.net.URL;
12 import java.net.URLConnection;
13 import java.nio.charset.Charset;
14 import java.nio.charset.StandardCharsets;
15 import java.nio.file.Files;
16 import java.security.KeyFactory;
17 import java.security.KeyManagementException;
18 import java.security.KeyStore;
19 import java.security.KeyStoreException;
20 import java.security.NoSuchAlgorithmException;
21 import java.security.UnrecoverableKeyException;
22 import java.security.cert.Certificate;
23 import java.security.cert.CertificateException;
24 import java.security.cert.CertificateFactory;
25 import java.security.cert.X509Certificate;
26 import java.security.interfaces.RSAPrivateKey;
27 import java.security.spec.InvalidKeySpecException;
28 import java.security.spec.PKCS8EncodedKeySpec;
29 import java.util.Base64;
30 import java.util.Map;
31
32 import javax.net.ssl.HostnameVerifier;
33 import javax.net.ssl.HttpsURLConnection;
34 import javax.net.ssl.KeyManager;
35 import javax.net.ssl.KeyManagerFactory;
36 import javax.net.ssl.SSLContext;
37 import javax.net.ssl.SSLSession;
38 import javax.net.ssl.TrustManager;
39 import javax.xml.bind.DatatypeConverter;
40
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
43
44 public class BaseHTTPClient {
45
46         private static Logger LOG = LoggerFactory.getLogger(BaseHTTPClient.class);
47         public static int SSLCERT_NONE=-1;
48         public static int SSLCERT_PCKS=0;
49         public static int SSLCERT_PEM=1;
50         private SSLContext sc=null;
51         private static final int BUFSIZE = 1024;
52         private static final Charset CHARSET = StandardCharsets.UTF_8;
53         private static final String SSLCONTEXT = "TLSv1.2";
54         private static final int DEFAULT_HTTP_TIMEOUT = 30000; //in ms
55         private boolean TRUSTALL;
56         private final String baseUrl;
57         private int timeout = DEFAULT_HTTP_TIMEOUT;
58
59         public BaseHTTPClient(String base) {
60                 this(base, false);
61         }
62         public BaseHTTPClient(String base, boolean trustAllCerts)
63         {
64                 this(base,trustAllCerts,null,null,SSLCERT_NONE);
65         }
66         public BaseHTTPClient(String base, boolean trustAllCerts,String certFilename,String passphrase,int sslCertType) {
67                 this.baseUrl = base;
68                 this.TRUSTALL = trustAllCerts;
69                 try {
70                         sc = setupSsl(TRUSTALL,certFilename,passphrase,sslCertType);
71                 } catch (KeyManagementException | NoSuchAlgorithmException | UnrecoverableKeyException | CertificateException | KeyStoreException | IOException | InvalidKeySpecException e) {
72                         LOG.warn("problem ssl setup: " + e.getMessage());
73                 }
74         }
75
76         protected BaseHTTPResponse sendRequest(String uri, String method, String body, Map<String, String> headers)
77                         throws IOException {
78                 return this.sendRequest(uri, method, body != null ? body.getBytes(CHARSET) : null, headers);
79         }
80
81         protected BaseHTTPResponse sendRequest(String uri, String method, byte[] body, Map<String, String> headers)
82                         throws IOException {
83                 if(uri==null)
84                         uri="";
85                 String surl = this.baseUrl;
86                 if(!surl.endsWith("/") && uri.length()>0)
87                         surl+="/";
88                 if(uri.startsWith("/"))
89                         uri=uri.substring(1);
90                 surl+=uri;
91                 LOG.debug("try to send request with url=" + this.baseUrl + uri + " as method=" + method);
92                 LOG.trace("body:" + (body==null?"null": new String(body, CHARSET)));
93                 URL url = new URL(surl);
94                 URLConnection http = url.openConnection();
95                 http.setConnectTimeout(this.timeout);
96                 if (surl.toString().startsWith("https"))
97                 {
98                         if (sc != null)
99                         {
100                                 ((HttpsURLConnection) http).setSSLSocketFactory(sc.getSocketFactory());
101                                 if (TRUSTALL) {
102                                         LOG.debug("trusting all certs");
103                                         HostnameVerifier allHostsValid = new HostnameVerifier() {
104                                                 public boolean verify(String hostname, SSLSession session) {
105                                                         return true;
106                                                 }
107                                         };
108                                         ((HttpsURLConnection) http).setHostnameVerifier(allHostsValid);
109                                 }
110                         } else //Should never happen
111                         {
112                         LOG.warn("No SSL context available");
113                         return new BaseHTTPResponse(-1, "");
114                         }
115                 }
116                 ((HttpURLConnection) http).setRequestMethod(method);
117                 http.setDoOutput(true);
118                 if (headers != null && headers.size() > 0) {
119                         for (String key : headers.keySet()) {
120                                 http.setRequestProperty(key, headers.get(key));
121                                 LOG.trace("set http header "+ key+": "+headers.get(key));
122                         }
123                 }
124                 byte[] buffer = new byte[BUFSIZE];
125                 int len = 0, lensum = 0;
126                 // send request
127                 // Send the message to destination
128                 if (!method.equals("GET") && body != null && body.length > 0) {
129                         try (OutputStream output = http.getOutputStream()) {
130                                 output.write(body);
131                         }
132                 }
133                 int responseCode = ((HttpURLConnection) http).getResponseCode();
134                 // Receive answer
135                 InputStream response;
136                 if (responseCode >= 200 && responseCode < 300)
137                         response = http.getInputStream();
138                 else {
139                         response = ((HttpURLConnection) http).getErrorStream();
140                         if (response == null)
141                                 response = http.getInputStream();
142                 }
143                 String sresponse = "";
144                 if (response != null) {
145                         while (true) {
146                                 len = response.read(buffer, 0, BUFSIZE);
147                                 if (len <= 0)
148                                         break;
149                                 lensum += len;
150                                 sresponse += new String(buffer, 0, len, CHARSET);
151                         }
152                         response.close();
153                 } else
154                         LOG.debug("response is null");
155                 LOG.debug("ResponseCode: " + responseCode);
156                 LOG.trace("Response (len:{}): {}",String.valueOf(lensum),sresponse);
157
158                 return new BaseHTTPResponse(responseCode, sresponse);
159         }
160
161         public static SSLContext setupSsl(boolean trustall)
162                         throws NoSuchAlgorithmException, KeyManagementException, CertificateException, FileNotFoundException,
163                         IOException, UnrecoverableKeyException, KeyStoreException, InvalidKeySpecException {
164
165                 return setupSsl(trustall, null, null, SSLCERT_NONE);
166         }
167
168         /**
169          *
170          * @param keyFilename
171          * @param certFilename
172          * @throws NoSuchAlgorithmException
173          * @throws KeyManagementException
174          * @throws IOException
175          * @throws FileNotFoundException
176          * @throws CertificateException
177          * @throws KeyStoreException
178          * @throws UnrecoverableKeyException
179          * @throws InvalidKeySpecException
180          */
181         public static SSLContext setupSsl(boolean trustall, String certFilename, String passPhrase,int certType) throws NoSuchAlgorithmException, KeyManagementException, CertificateException, FileNotFoundException, IOException, UnrecoverableKeyException, KeyStoreException, InvalidKeySpecException {
182
183                 SSLContext sc = SSLContext.getInstance(SSLCONTEXT);
184                 TrustManager[] trustCerts = null;
185                 if (trustall) {
186                         trustCerts = new TrustManager[] { new javax.net.ssl.X509TrustManager() {
187                                 public java.security.cert.X509Certificate[] getAcceptedIssuers() {
188                                         return null;
189                                 }
190
191                                 public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {
192                                 }
193
194                                 public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {
195                                 }
196                         } };
197
198                 }
199                 KeyManager[] kms=null;
200                 if(certFilename!=null && passPhrase!=null && !certFilename.isEmpty() && !passPhrase.isEmpty())
201                 {
202                         if(certType==SSLCERT_PCKS)
203                         {
204                                 LOG.debug("try to load pcks file "+certFilename+ " with passphrase="+passPhrase);
205                                 KeyStore keyStore = KeyStore.getInstance("PKCS12");
206                                 keyStore.load(new FileInputStream(certFilename), passPhrase.toCharArray());
207                                 KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
208                         kmf.init(keyStore, passPhrase.toCharArray());
209                         kms = kmf.getKeyManagers();
210                         LOG.debug("successful");
211
212                         }
213                         else if(certType==SSLCERT_PEM)
214                         {
215                                 LOG.debug("try to load pem files cert="+certFilename+ " key="+passPhrase);
216                                 File fCert = new File(certFilename);
217                                 File fKey = new File(passPhrase);
218                                 KeyStore keyStore = KeyStore.getInstance("JKS");
219                                 keyStore.load(null);
220                                 byte[] certBytes = parseDERFromPEM(Files.readAllBytes(fCert.toPath()), "-----BEGIN CERTIFICATE-----",
221                                                 "-----END CERTIFICATE-----");
222                                 byte[] keyBytes = parseDERFromPEM(Files.readAllBytes(fKey.toPath()), "-----BEGIN PRIVATE KEY-----",
223                                                 "-----END PRIVATE KEY-----");
224
225                                 X509Certificate cert = generateCertificateFromDER(certBytes);
226                                 RSAPrivateKey key = generatePrivateKeyFromDER(keyBytes);
227                                 keyStore.setCertificateEntry("cert-alias", cert);
228                             keyStore.setKeyEntry("key-alias", key, "changeit".toCharArray(), new Certificate[] {cert});
229
230                             KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
231                             kmf.init(keyStore, "changeit".toCharArray());
232                             kms = kmf.getKeyManagers();
233                             LOG.debug("successful");
234                         }
235                 }
236                 // Init the SSLContext with a TrustManager[] and SecureRandom()
237                 sc.init(kms, trustCerts, new java.security.SecureRandom());
238                 return sc;
239         }
240         protected static byte[] parseDERFromPEM(byte[] pem, String beginDelimiter, String endDelimiter) {
241             String data = new String(pem);
242             String[] tokens = data.split(beginDelimiter);
243             tokens = tokens[1].split(endDelimiter);
244             return DatatypeConverter.parseBase64Binary(tokens[0]);
245         }
246
247         protected static RSAPrivateKey generatePrivateKeyFromDER(byte[] keyBytes) throws InvalidKeySpecException, NoSuchAlgorithmException {
248             PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
249
250             KeyFactory factory = KeyFactory.getInstance("RSA");
251
252             return (RSAPrivateKey)factory.generatePrivate(spec);
253         }
254
255         protected static X509Certificate generateCertificateFromDER(byte[] certBytes) throws CertificateException {
256             CertificateFactory factory = CertificateFactory.getInstance("X.509");
257
258             return (X509Certificate)factory.generateCertificate(new ByteArrayInputStream(certBytes));
259         }
260         public static String getAuthorizationHeaderValue(String username, String password) {
261                 return "Basic " + new String(Base64.getEncoder().encode((username+":"+password).getBytes()));
262         }
263         public void setTimeout(int timeout) {
264                 this.timeout =timeout;
265         }
266
267 }