Lwm2m base64 back fix bug "bas64" on review

This commit is contained in:
nickAS21 2021-09-30 12:24:29 +03:00
parent e8444f8bdc
commit 9186377b97
7 changed files with 73 additions and 71 deletions

View File

@ -1,45 +0,0 @@
/**
* Copyright © 2016-2021 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.common.data.device.credentials.lwm2m;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
import lombok.Setter;
import lombok.SneakyThrows;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
public abstract class AbstractLwM2MClientCredentialsWithKey extends AbstractLwM2MClientCredentials {
@Getter
@Setter
private String key;
private byte[] keyInBytes;
@SneakyThrows
@JsonIgnore
public byte[] getDecodedKey() throws IllegalArgumentException {
if (keyInBytes == null) {
if (this.getSecurityConfigClientMode() == LwM2MSecurityMode.PSK) {
keyInBytes = Hex.decodeHex(key.toLowerCase().toCharArray());
}
else {
keyInBytes = Base64.decodeBase64(key.getBytes());
}
}
return keyInBytes;
}
}

View File

@ -0,0 +1,30 @@
/**
* Copyright © 2016-2021 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.common.data.device.credentials.lwm2m;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.codec.DecoderException;
public abstract class AbstractLwM2MClientSecurityCredentials extends AbstractLwM2MClientCredentials {
@Getter
@Setter
protected String key;
protected byte[] securityInBytes;
public abstract byte[] getDecoded() throws IllegalArgumentException, DecoderException;
}

View File

@ -17,14 +17,24 @@ package org.thingsboard.server.common.data.device.credentials.lwm2m;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
@Getter @Getter
@Setter @Setter
public class PSKClientCredentials extends AbstractLwM2MClientCredentialsWithKey { public class PSKClientCredentials extends AbstractLwM2MClientSecurityCredentials {
private String identity; private String identity;
@Override @Override
public LwM2MSecurityMode getSecurityConfigClientMode() { public LwM2MSecurityMode getSecurityConfigClientMode() {
return LwM2MSecurityMode.PSK; return LwM2MSecurityMode.PSK;
} }
}
@Override
public byte[] getDecoded() throws IllegalArgumentException, DecoderException {
if (securityInBytes == null) {
securityInBytes = Hex.decodeHex(key.toLowerCase().toCharArray());
}
return securityInBytes;
}
}

View File

@ -15,10 +15,21 @@
*/ */
package org.thingsboard.server.common.data.device.credentials.lwm2m; package org.thingsboard.server.common.data.device.credentials.lwm2m;
public class RPKClientCredentials extends AbstractLwM2MClientCredentialsWithKey { import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Base64;
public class RPKClientCredentials extends AbstractLwM2MClientSecurityCredentials {
@Override @Override
public LwM2MSecurityMode getSecurityConfigClientMode() { public LwM2MSecurityMode getSecurityConfigClientMode() {
return LwM2MSecurityMode.RPK; return LwM2MSecurityMode.RPK;
} }
@Override
public byte[] getDecoded() throws IllegalArgumentException, DecoderException {
if (securityInBytes == null) {
securityInBytes = Base64.decodeBase64(key.getBytes());
}
return securityInBytes;
}
} }

View File

@ -15,30 +15,27 @@
*/ */
package org.thingsboard.server.common.data.device.credentials.lwm2m; package org.thingsboard.server.common.data.device.credentials.lwm2m;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import lombok.SneakyThrows; import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Base64;
@Getter @Getter
@Setter @Setter
public class X509ClientCredentials extends AbstractLwM2MClientCredentials { public class X509ClientCredentials extends AbstractLwM2MClientSecurityCredentials {
private String cert;
private byte[] certInBytes; private String cert;
@Override @Override
public LwM2MSecurityMode getSecurityConfigClientMode() { public LwM2MSecurityMode getSecurityConfigClientMode() {
return LwM2MSecurityMode.X509; return LwM2MSecurityMode.X509;
} }
@SneakyThrows @Override
@JsonIgnore public byte[] getDecoded() throws IllegalArgumentException, DecoderException {
public byte[] getDecodedCert() throws IllegalArgumentException { if (securityInBytes == null && cert != null) {
if (certInBytes == null) { securityInBytes = Base64.decodeBase64(cert.getBytes());
certInBytes = Base64.decodeBase64(cert.getBytes());
} }
return certInBytes; return securityInBytes;
} }
} }

View File

@ -17,6 +17,7 @@ package org.thingsboard.server.transport.lwm2m.secure;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.DecoderException;
import org.eclipse.leshan.core.util.SecurityUtil; import org.eclipse.leshan.core.util.SecurityUtil;
import org.eclipse.leshan.server.security.SecurityInfo; import org.eclipse.leshan.server.security.SecurityInfo;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -146,14 +147,14 @@ public class LwM2mCredentialsSecurityInfoValidator {
PSKClientCredentials pskConfig = (PSKClientCredentials) clientCredentialsConfig; PSKClientCredentials pskConfig = (PSKClientCredentials) clientCredentialsConfig;
if (StringUtils.isNotEmpty(pskConfig.getIdentity())) { if (StringUtils.isNotEmpty(pskConfig.getIdentity())) {
try { try {
if (pskConfig.getDecodedKey() != null && pskConfig.getDecodedKey().length > 0) { if (pskConfig.getDecoded() != null && pskConfig.getDecoded().length > 0) {
endpoint = StringUtils.isNotEmpty(pskConfig.getEndpoint()) ? pskConfig.getEndpoint() : endpoint; endpoint = StringUtils.isNotEmpty(pskConfig.getEndpoint()) ? pskConfig.getEndpoint() : endpoint;
if (endpoint != null && !endpoint.isEmpty()) { if (endpoint != null && !endpoint.isEmpty()) {
result.setSecurityInfo(SecurityInfo.newPreSharedKeyInfo(endpoint, pskConfig.getIdentity(), pskConfig.getDecodedKey())); result.setSecurityInfo(SecurityInfo.newPreSharedKeyInfo(endpoint, pskConfig.getIdentity(), pskConfig.getDecoded()));
result.setSecurityMode(PSK); result.setSecurityMode(PSK);
} }
} }
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException | DecoderException e) {
log.error("Missing PSK key: " + e.getMessage()); log.error("Missing PSK key: " + e.getMessage());
} }
} else { } else {
@ -164,14 +165,14 @@ public class LwM2mCredentialsSecurityInfoValidator {
private void createClientSecurityInfoRPK(TbLwM2MSecurityInfo result, String endpoint, LwM2MClientCredentials clientCredentialsConfig) { private void createClientSecurityInfoRPK(TbLwM2MSecurityInfo result, String endpoint, LwM2MClientCredentials clientCredentialsConfig) {
RPKClientCredentials rpkConfig = (RPKClientCredentials) clientCredentialsConfig; RPKClientCredentials rpkConfig = (RPKClientCredentials) clientCredentialsConfig;
try { try {
if (rpkConfig.getDecodedKey() != null) { if (rpkConfig.getDecoded() != null) {
PublicKey key = SecurityUtil.publicKey.decode(rpkConfig.getDecodedKey()); PublicKey key = SecurityUtil.publicKey.decode(rpkConfig.getDecoded());
result.setSecurityInfo(SecurityInfo.newRawPublicKeyInfo(endpoint, key)); result.setSecurityInfo(SecurityInfo.newRawPublicKeyInfo(endpoint, key));
result.setSecurityMode(RPK); result.setSecurityMode(RPK);
} else { } else {
log.error("Missing RPK key"); log.error("Missing RPK key");
} }
} catch (IllegalArgumentException | IOException | GeneralSecurityException e) { } catch (IllegalArgumentException | IOException | GeneralSecurityException | DecoderException e) {
log.error("RPK: Invalid security info content: " + e.getMessage()); log.error("RPK: Invalid security info content: " + e.getMessage());
} }
} }

View File

@ -117,7 +117,7 @@ public class DeviceCredentialsServiceImpl extends AbstractEntityService implemen
formatSimpleMqttCredentials(deviceCredentials); formatSimpleMqttCredentials(deviceCredentials);
break; break;
case LWM2M_CREDENTIALS: case LWM2M_CREDENTIALS:
formatSimpleLwm2mCredentials(deviceCredentials); formatAndValidateSimpleLwm2mCredentials(deviceCredentials);
break; break;
} }
} }
@ -160,7 +160,7 @@ public class DeviceCredentialsServiceImpl extends AbstractEntityService implemen
deviceCredentials.setCredentialsValue(cert); deviceCredentials.setCredentialsValue(cert);
} }
private void formatSimpleLwm2mCredentials(DeviceCredentials deviceCredentials) { private void formatAndValidateSimpleLwm2mCredentials(DeviceCredentials deviceCredentials) {
LwM2MDeviceCredentials lwM2MCredentials; LwM2MDeviceCredentials lwM2MCredentials;
try { try {
lwM2MCredentials = JacksonUtil.fromString(deviceCredentials.getCredentialsValue(), LwM2MDeviceCredentials.class); lwM2MCredentials = JacksonUtil.fromString(deviceCredentials.getCredentialsValue(), LwM2MDeviceCredentials.class);
@ -171,8 +171,6 @@ public class DeviceCredentialsServiceImpl extends AbstractEntityService implemen
String credentialsId = null; String credentialsId = null;
LwM2MClientCredentials clientCredentials = lwM2MCredentials.getClient(); LwM2MClientCredentials clientCredentials = lwM2MCredentials.getClient();
LwM2MServerCredentials bootstrapServer = lwM2MCredentials.getBootstrap().getBootstrapServer();
LwM2MServerCredentials lwm2mServer = lwM2MCredentials.getBootstrap().getLwm2mServer();
switch (clientCredentials.getSecurityConfigClientMode()) { switch (clientCredentials.getSecurityConfigClientMode()) {
case NO_SEC: case NO_SEC:
case RPK: case RPK:
@ -264,7 +262,7 @@ public class DeviceCredentialsServiceImpl extends AbstractEntityService implemen
try { try {
String pubkClient = EncryptionUtil.pubkTrimNewLines(rpkCredentials.getKey()); String pubkClient = EncryptionUtil.pubkTrimNewLines(rpkCredentials.getKey());
rpkCredentials.setKey(pubkClient); rpkCredentials.setKey(pubkClient);
SecurityUtil.publicKey.decode(rpkCredentials.getDecodedKey()); SecurityUtil.publicKey.decode(rpkCredentials.getDecoded());
} catch (Exception e) { } catch (Exception e) {
throw new DeviceCredentialsValidationException("LwM2M client RPK key should be in RFC7250 standard and support only EC algorithm and encoded to Base64 format!"); throw new DeviceCredentialsValidationException("LwM2M client RPK key should be in RFC7250 standard and support only EC algorithm and encoded to Base64 format!");
} }
@ -275,7 +273,7 @@ public class DeviceCredentialsServiceImpl extends AbstractEntityService implemen
try { try {
String certClient = EncryptionUtil.certTrimNewLines(x509CCredentials.getCert()); String certClient = EncryptionUtil.certTrimNewLines(x509CCredentials.getCert());
x509CCredentials.setCert(certClient); x509CCredentials.setCert(certClient);
SecurityUtil.certificate.decode(x509CCredentials.getDecodedCert()); SecurityUtil.certificate.decode(x509CCredentials.getDecoded());
} catch (Exception e) { } catch (Exception e) {
throw new DeviceCredentialsValidationException("LwM2M client X509 certificate should be in DER-encoded X509v3 format and support only EC algorithm and encoded to Base64 format!"); throw new DeviceCredentialsValidationException("LwM2M client X509 certificate should be in DER-encoded X509v3 format and support only EC algorithm and encoded to Base64 format!");
} }