/** * diqube: Distributed Query Base. * * Copyright (C) 2015 Bastian Gloeckle * * This file is part of diqube. * * diqube is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.diqube.connection.integrity; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javax.annotation.PostConstruct; import org.diqube.config.Config; import org.diqube.config.ConfigKey; import org.diqube.context.AutoInstatiate; /** * Helper for the configKeys {@link ConfigKey#MESSAGE_INTEGRITY_SECRET}, * {@link ConfigKey#MESSAGE_INTEGRITY_SECRET_ALTERNATIVE1} and {@link ConfigKey#MESSAGE_INTEGRITY_SECRET_ALTERNATIVE2} * in order to transform them into a form where they can be used for {@link IntegrityCheckingProtocol}. * * @author Bastian Gloeckle */ @AutoInstatiate public class IntegritySecretHelper { private static final String NONE = "none"; @Config(ConfigKey.MESSAGE_INTEGRITY_SECRET) private String messageIntegritySecret; @Config(ConfigKey.MESSAGE_INTEGRITY_SECRET_ALTERNATIVE1) private String messageIntegritySecretAlternative1; @Config(ConfigKey.MESSAGE_INTEGRITY_SECRET_ALTERNATIVE2) private String messageIntegritySecretAlternative2; @PostConstruct public void initialize() { if (messageIntegritySecret == null || "".equals(messageIntegritySecret.trim())) throw new RuntimeException( "No config value set for " + ConfigKey.MESSAGE_INTEGRITY_SECRET + ", but one is needed!"); messageIntegritySecret = messageIntegritySecret.trim(); if (messageIntegritySecretAlternative1 != null) messageIntegritySecretAlternative1 = messageIntegritySecretAlternative1.trim(); if ("".equals(messageIntegritySecretAlternative1)) messageIntegritySecretAlternative1 = NONE; if (messageIntegritySecretAlternative2 != null) messageIntegritySecretAlternative2 = messageIntegritySecretAlternative2.trim(); if ("".equals(messageIntegritySecretAlternative2)) messageIntegritySecretAlternative2 = NONE; } /** * @return The MAC keys to be used with {@link IntegrityCheckingProtocol}. */ public byte[][] provideMessageIntegritySecrets() { List<byte[]> res = new ArrayList<>(); if (messageIntegritySecret.startsWith("0x")) res.add(hexStringToBytes(messageIntegritySecret)); else res.add(messageIntegritySecret.getBytes(Charset.forName("UTF-8"))); for (String k : Arrays.asList(messageIntegritySecretAlternative1, messageIntegritySecretAlternative2)) { if (k == null || k.equals(NONE)) continue; if (k.startsWith("0x")) res.add(hexStringToBytes(k)); else res.add(k.getBytes(Charset.forName("UTF-8"))); } return res.toArray(new byte[res.size()][]); } private byte[] hexStringToBytes(String hexString) { byte[] res = new byte[(int) Math.ceil((hexString.length() - 2) / 2.)]; int resPos = 0; for (int i = 2; i < hexString.length(); i += 2) { String s = hexString.substring(i, i + 2); if (s.length() == 1) s += "0"; s = "0x" + s; res[resPos++] = Byte.decode(s); } return res; } /** for tests */ /* package */ void setMessageIntegritySecret(String messageIntegritySecret) { this.messageIntegritySecret = messageIntegritySecret; } }