]> git.basschouten.com Git - openhab-addons.git/blob
5fa2820edee709798ce5a9788d93a39d346d632c
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2022 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.hue.internal.connection;
14
15 import java.io.IOException;
16 import java.io.InputStream;
17 import java.net.MalformedURLException;
18 import java.net.URL;
19 import java.nio.charset.StandardCharsets;
20 import java.security.cert.CertificateException;
21
22 import javax.net.ssl.X509ExtendedTrustManager;
23
24 import org.eclipse.jdt.annotation.NonNullByDefault;
25 import org.eclipse.jdt.annotation.Nullable;
26 import org.openhab.core.io.net.http.PEMTrustManager;
27 import org.openhab.core.io.net.http.PEMTrustManager.CertificateInstantiationException;
28 import org.openhab.core.io.net.http.TlsTrustManagerProvider;
29 import org.openhab.core.io.net.http.TrustAllTrustManager;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32
33 /**
34  * Provides a {@link PEMTrustManager} to allow secure connections to any Hue Bridge.
35  *
36  * @author Christoph Weitkamp - Initial Contribution
37  */
38 @NonNullByDefault
39 public class HueTlsTrustManagerProvider implements TlsTrustManagerProvider {
40
41     private static final String PEM_FILENAME = "huebridge_cacert.pem";
42     private final String hostname;
43     private final boolean useSelfSignedCertificate;
44
45     private final Logger logger = LoggerFactory.getLogger(HueTlsTrustManagerProvider.class);
46
47     public HueTlsTrustManagerProvider(String hostname, boolean useSelfSignedCertificate) {
48         this.hostname = hostname;
49         this.useSelfSignedCertificate = useSelfSignedCertificate;
50     }
51
52     @Override
53     public String getHostName() {
54         return hostname;
55     }
56
57     @Override
58     public X509ExtendedTrustManager getTrustManager() {
59         try {
60             if (useSelfSignedCertificate) {
61                 logger.trace("Use self-signed certificate downloaded from Hue Bridge.");
62                 // use self-signed certificate downloaded from Hue Bridge
63                 return PEMTrustManager.getInstanceFromServer("https://" + getHostName());
64             } else {
65                 logger.trace("Use Signify private CA Certificate for Hue Bridges from resources.");
66                 // use Signify private CA Certificate for Hue Bridges from resources
67                 return getInstanceFromResource(PEM_FILENAME);
68             }
69         } catch (CertificateException | MalformedURLException e) {
70             logger.error("An unexpected exception occurred - returning a TrustAllTrustManager: {}", e.getMessage(), e);
71         }
72         return TrustAllTrustManager.getInstance();
73     }
74
75     /**
76      * Creates a {@link PEMTrustManager} instance by reading the PEM certificate from the given file.
77      * This is useful if you have a private CA Certificate stored in a file.
78      *
79      * @param fileName name to the PEM file located in the resources folder
80      * @return a {@link PEMTrustManager} instance
81      * @throws CertificateInstantiationException
82      */
83     private PEMTrustManager getInstanceFromResource(String fileName) throws CertificateException {
84         String pemCert = readPEMCertificateStringFromResource(fileName);
85         if (pemCert != null) {
86             return new PEMTrustManager(pemCert);
87         }
88         throw new CertificateInstantiationException(
89                 String.format("Certificate resource '%s' not found or not accessible.", fileName));
90     }
91
92     private @Nullable String readPEMCertificateStringFromResource(String fileName) {
93         URL resource = Thread.currentThread().getContextClassLoader().getResource(fileName);
94         if (resource != null) {
95             try (InputStream certInputStream = resource.openStream()) {
96                 return new String(certInputStream.readAllBytes(), StandardCharsets.UTF_8);
97             } catch (IOException e) {
98                 logger.error("An unexpected exception occurred: ", e);
99             }
100         }
101         return null;
102     }
103 }