/*
* Kontalk Java client
* Copyright (C) 2016 Kontalk Devteam <devteam@kontalk.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.kontalk.crypto;
import java.io.File;
import java.util.HashMap;
import java.util.Optional;
import java.util.logging.Logger;
import org.kontalk.crypto.PGPUtils.PGPCoderKey;
import org.kontalk.model.Contact;
import org.kontalk.model.message.DecryptMessage;
import org.kontalk.model.message.MessageContent.InAttachment;
import org.kontalk.model.message.OutMessage;
/**
* Static methods for decryption and encryption of a message.
*
* @author Alexander Bikadorov {@literal <bikaejkb@mail.tu-berlin.de>}
*/
public final class Coder {
private static final Logger LOGGER = Logger.getLogger(Coder.class.getName());
private Coder() {
}
/**
* Encryption status of a message.
* Do not modify, only add! Ordinal used in database.
*/
public enum Encryption {NOT, ENCRYPTED, DECRYPTED}
/**
* Signing status of a message.
* Do not modify, only add! Ordinal used in database.
*/
public enum Signing {NOT, SIGNED, VERIFIED, UNKNOWN}
/**
* Errors that can occur during de-/encryption and verification.
* Do not modify, only add! Ordinal used in database.
*/
public enum Error {
/** Some unknown error. */
UNKNOWN_ERROR,
/** Own personal key not found. Unused. */
MY_KEY_UNAVAILABLE,
/** Public key of sender not found. */
KEY_UNAVAILABLE,
/** My private key does not match. */
INVALID_PRIVATE_KEY,
/** Invalid data / parsing failed. */
INVALID_DATA,
/** No integrity protection found. */
NO_INTEGRITY,
/** Integrity check failed. */
INVALID_INTEGRITY,
/** Invalid data / parsing failed of signature. */
INVALID_SIGNATURE_DATA,
/** Signature does not match sender. */
INVALID_SIGNATURE,
/** Recipient user id in decrypted data does not match id in my key. */
INVALID_RECIPIENT,
/** Sender user id in decrypted data does not match id in sender key. */
INVALID_SENDER,
//INVALID_MIME,
//INVALID_TIMESTAMP,
}
private static final HashMap<Contact, PGPCoderKey> KEY_MAP = new HashMap<>();
public static Optional<PGPCoderKey> contactkey(Contact contact) {
if (KEY_MAP.containsKey(contact)) {
PGPCoderKey key = KEY_MAP.get(contact);
if (key.fingerprint.equals(contact.getFingerprint()))
return Optional.of(key);
}
byte[] rawKey = contact.getKey();
if (rawKey.length != 0) {
PGPCoderKey key = PGPUtils.readPublicKey(rawKey).orElse(null);
if (key != null) {
KEY_MAP.put(contact, key);
return Optional.of(key);
}
}
LOGGER.warning("key not found for contact: "+contact);
return Optional.empty();
}
/**
* Decrypt and verify the body of a message. Sets the encryption and signing
* status of the message and errors that may occur are saved to the message.
*/
public static boolean decryptMessage(PersonalKey myKey, DecryptMessage message) {
return Decryptor.decryptMessage(message, myKey);
}
/**
* Decrypt and verify a downloaded attachment file. Sets the encryption and
* signing status of the message attachment and errors that may occur are
* saved to the attachment.
*/
public static void decryptAttachment(PersonalKey myKey, InAttachment attachment, Contact sender) {
Decryptor.decryptAttachment(attachment, myKey, sender);
}
/**
* Creates encrypted and signed message body.
* Errors that may occur are saved to the message.
* @return the encrypted and signed text.
*/
public static String encryptMessageRFC3923(PersonalKey myKey, OutMessage message) {
return new Encryptor(myKey, message).encryptMessageRFC3923();
}
public static String encryptStanzaRFC3923(PersonalKey myKey, OutMessage message, String xml) {
return new Encryptor(myKey, message).encryptStanzaRFC3923(xml);
}
/** Encrypt an arbitrary UTF-8 string as a Base64 encoded OpenPGP Message. */
public static String encryptString(PersonalKey myKey, OutMessage message, String plainText) {
return new Encryptor(myKey, message).encryptString(plainText);
}
public static Optional<File> encryptAttachment(PersonalKey myKey, OutMessage message, File file) {
return new Encryptor(myKey, message).encryptAttachment(file);
}
}