/** * Construct a {@link SecurityInfo} when using DTLS with an X509 Certificate. */ public static SecurityInfo newX509CertInfo(String endpoint) { return new SecurityInfo(endpoint, null, null, null, true); }
public DefaultAuthorizer(SecurityStore store) { this(store, new SecurityChecker()); }
@Override public byte[] getKey(String identity) { if (securityStore == null) return null; SecurityInfo info = securityStore.getByIdentity(identity); if (info == null || info.getPreSharedKey() == null) { return null; } else { // defensive copy return Arrays.copyOf(info.getPreSharedKey(), info.getPreSharedKey().length); } }
@Override public SecurityInfo add(SecurityInfo info) throws NonUniqueSecurityInfoException { writeLock.lock(); try { String identity = info.getIdentity(); if (identity != null) { SecurityInfo infoByIdentity = securityByIdentity.get(info.getIdentity()); if (infoByIdentity != null && !info.getEndpoint().equals(infoByIdentity.getEndpoint())) { throw new NonUniqueSecurityInfoException("PSK Identity " + info.getIdentity() + " is already used"); } securityByIdentity.put(info.getIdentity(), info); } SecurityInfo previous = securityByEp.put(info.getEndpoint(), info); String previousIdentity = previous == null ? null : previous.getIdentity(); if (previousIdentity != null && !previousIdentity.equals(identity)) { securityByIdentity.remove(previousIdentity); } return previous; } finally { writeLock.unlock(); } }
@Override public String getIdentity(InetSocketAddress inetAddress) { if (registrationStore == null) return null; Registration registration = registrationStore.getRegistrationByAdress(inetAddress); if (registration != null) { SecurityInfo securityInfo = securityStore.getByEndpoint(registration.getEndpoint()); if (securityInfo != null) { return securityInfo.getIdentity(); } return null; } return null; }
protected boolean checkPskIdentity(String endpoint, Identity clientIdentity, SecurityInfo securityInfo) { // Manage PSK authentication // ---------------------------------------------------- if (!securityInfo.usePSK()) { LOG.debug("Client '{}' is not supposed to use PSK to authenticate", endpoint); return false; } if (!matchPskIdentity(endpoint, clientIdentity.getPskIdentity(), securityInfo.getIdentity())) { return false; } LOG.trace("Authenticated client '{}' using DTLS PSK", endpoint); return true; }
protected boolean checkRpkIdentity(String endpoint, Identity clientIdentity, SecurityInfo securityInfo) { // Manage RPK authentication // ---------------------------------------------------- if (!securityInfo.useRPK()) { LOG.debug("Client '{}' is not supposed to use RPK to authenticate", endpoint); return false; } if (!matchRpkIdenity(endpoint, clientIdentity.getRawPublicKey(), securityInfo.getRawPublicKey())) { return false; } LOG.trace("authenticated client '{}' using DTLS RPK", endpoint); return true; }
@Override public byte[] getKey(String identity) { SecurityInfo info = bsSecurityStore.getByIdentity(identity); if (info == null || info.getPreSharedKey() == null) { return null; } else { // defensive copy return Arrays.copyOf(info.getPreSharedKey(), info.getPreSharedKey().length); } }
/** * {@inheritDoc} */ @Override protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String[] path = StringUtils.split(req.getPathInfo(), '/'); if (path.length != 1 && "clients".equals(path[0])) { resp.sendError(HttpServletResponse.SC_BAD_REQUEST); return; } try { SecurityInfo info = gsonDes.fromJson(new InputStreamReader(req.getInputStream()), SecurityInfo.class); LOG.debug("New security info for end-point {}: {}", info.getEndpoint(), info); store.add(info); resp.setStatus(HttpServletResponse.SC_OK); } catch (NonUniqueSecurityInfoException e) { LOG.warn("Non unique security info: " + e.getMessage()); resp.setStatus(HttpServletResponse.SC_BAD_REQUEST); resp.getWriter().append(e.getMessage()).flush(); } catch (JsonParseException e) { LOG.warn("Could not parse request body", e); resp.setStatus(HttpServletResponse.SC_BAD_REQUEST); resp.getWriter().append("Invalid request body").flush(); } catch (RuntimeException e) { LOG.warn("unexpected error for request " + req.getPathInfo(), e); resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } }
protected boolean checkX509Identity(String endpoint, Identity clientIdentity, SecurityInfo securityInfo) { // Manage X509 certificate authentication // ---------------------------------------------------- if (!securityInfo.useX509Cert()) { LOG.debug("Client '{}' is not supposed to use X509 certificate to authenticate", endpoint); return false; } if (!matchX509Identity(endpoint, clientIdentity.getX509CommonName(), endpoint)) { return false; } LOG.trace("authenticated client '{}' using DTLS X509 certificates", endpoint); return true; }
@Override public SecurityInfo remove(String endpoint) { writeLock.lock(); try { SecurityInfo info = securityByEp.get(endpoint); if (info != null) { if (info.getIdentity() != null) { securityByIdentity.remove(info.getIdentity()); } securityByEp.remove(endpoint); } return info; } finally { writeLock.unlock(); } } }
@Override public Registration isAuthorized(UplinkRequest<?> request, Registration registration, Identity senderIdentity) { // do we have security information for this client? SecurityInfo expectedSecurityInfo = null; if (securityStore != null) expectedSecurityInfo = securityStore.getByEndpoint(registration.getEndpoint()); if (securityChecker.checkSecurityInfo(registration.getEndpoint(), senderIdentity, expectedSecurityInfo)) { return registration; } else { return null; } } }
@Override public BootstrapSession begin(String endpoint, Identity clientIdentity) { boolean authorized; if (bsSecurityStore != null) { List<SecurityInfo> securityInfos = bsSecurityStore.getAllByEndpoint(endpoint); authorized = securityChecker.checkSecurityInfos(endpoint, clientIdentity, securityInfos); } else { authorized = true; } return new DefaultBootstrapSession(endpoint, clientIdentity, authorized); }
@Override public SecurityInfo add(SecurityInfo info) throws NonUniqueSecurityInfoException { byte[] data = serialize(info); try (Jedis j = pool.getResource()) { if (info.getIdentity() != null) { // populate the secondary index (security info by PSK id) String oldEndpoint = j.hget(PSKID_SEC, info.getIdentity()); if (oldEndpoint != null && !oldEndpoint.equals(info.getEndpoint())) { throw new NonUniqueSecurityInfoException("PSK Identity " + info.getIdentity() + " is already used"); } j.hset(PSKID_SEC.getBytes(), info.getIdentity().getBytes(), info.getEndpoint().getBytes()); } byte[] previousData = j.getSet((SEC_EP + info.getEndpoint()).getBytes(), data); SecurityInfo previous = previousData == null ? null : deserialize(previousData); String previousIdentity = previous == null ? null : previous.getIdentity(); if (previousIdentity != null && !previousIdentity.equals(info.getIdentity())) { j.hdel(PSKID_SEC, previousIdentity); } return previous; } }
@Override public String getIdentity(InetSocketAddress inetAddress) { if (clientRegistry == null) return null; for (Client c : clientRegistry.allClients()) { if (inetAddress.getPort() == c.getPort() && inetAddress.getAddress().equals(c.getAddress())) { SecurityInfo securityInfo = securityStore.getByEndpoint(c.getEndpoint()); if (securityInfo != null) { return securityInfo.getIdentity(); } return null; } } return null; } }
@Override public byte[] getKey(String identity) { SecurityInfo info = securityStore.getByIdentity(identity); if (info == null || info.getPreSharedKey() == null) { return null; } else { // defensive copy return Arrays.copyOf(info.getPreSharedKey(), info.getPreSharedKey().length); } }
/** * Construct a {@link SecurityInfo} when using DTLS with Raw Public Key (RPK). */ public static SecurityInfo newRawPublicKeyInfo(String endpoint, PublicKey rawPublicKey) { Validate.notNull(rawPublicKey); return new SecurityInfo(endpoint, null, null, rawPublicKey, false); }
public DefaultBootstrapSessionManager(BootstrapSecurityStore bsSecurityStore) { this(bsSecurityStore, new SecurityChecker()); }
@Override public SecurityInfo add(SecurityInfo info) throws NonUniqueSecurityInfoException { byte[] data = serialize(info); try (Jedis j = pool.getResource()) { if (info.getIdentity() != null) { // populate the secondary index (security info by PSK id) String oldEndpoint = j.hget(PSKID_SEC, info.getIdentity()); if (oldEndpoint != null && !oldEndpoint.equals(info.getEndpoint())) { throw new NonUniqueSecurityInfoException("PSK Identity " + info.getIdentity() + " is already used"); } j.hset(PSKID_SEC.getBytes(), info.getIdentity().getBytes(), info.getEndpoint().getBytes()); } byte[] previousData = j.getSet((SEC_EP + info.getEndpoint()).getBytes(), data); SecurityInfo previous = previousData == null ? null : deserialize(previousData); String previousIdentity = previous == null ? null : previous.getIdentity(); if (previousIdentity != null && !previousIdentity.equals(info.getIdentity())) { j.hdel(PSKID_SEC, previousIdentity); } return previous; } }
/** * Construct a {@link SecurityInfo} when using DTLS with Pre-Shared Keys. */ public static SecurityInfo newPreSharedKeyInfo(String endpoint, String identity, byte[] preSharedKey) { Validate.notEmpty(identity); Validate.notNull(preSharedKey); return new SecurityInfo(endpoint, identity, preSharedKey, null, false); }