use of i2p.bote.crypto.CryptoImplementation in project i2p.i2p-bote by i2p.
the class GeneralHelper method createOrModifyIdentity.
/**
* Updates an email identity if <code>createNew</code> is <code>false</code>,
* or adds a new identity if <code>createNew</code> is <code>true</code>.
* @param createNew
* @param cryptoImplId The id value of the cryptographic algorithm set to use for the new identity; ignored if <code>createNew</code> is <code>false</code>
* @param vanityPrefix An alphanumeric string the destination should start with; ignored if <code>createNew==false</code>.
* @param key A base64-encoded Email Destination key
* @param description
* @param publicName
* @param picture
* @param emailAddress
* @param setDefault If this is <code>true</code>, the identity becomes the new default identity. Otherwise, the default stays the same.
* @throws GeneralSecurityException
* @throws PasswordException
* @throws IOException
* @throws IllegalDestinationParametersException if <code>cryptoImplId</code> and <code>vanityPrefix</code> aren't compatible
*/
public static void createOrModifyIdentity(boolean createNew, int cryptoImplId, String vanityPrefix, String key, String publicName, String description, String pictureBase64, String emailAddress, Properties config, boolean setDefault, StatusListener<ChangeIdentityStatus> lsnr) throws GeneralSecurityException, PasswordException, IOException, IllegalDestinationParametersException {
Log log = new Log(GeneralHelper.class);
Identities identities = I2PBote.getInstance().getIdentities();
EmailIdentity identity;
if (createNew) {
CryptoImplementation cryptoImpl = CryptoFactory.getInstance(cryptoImplId);
if (cryptoImpl == null) {
log.error("Invalid ID number for CryptoImplementation: " + cryptoImplId);
throw new IllegalArgumentException("Invalid ID number for CryptoImplementation: " + cryptoImplId);
}
lsnr.updateStatus(ChangeIdentityStatus.GENERATING_KEYS);
try {
identity = new EmailIdentity(cryptoImpl, vanityPrefix);
} catch (GeneralSecurityException e) {
log.error("Can't generate email identity for CryptoImplementation: <" + cryptoImpl + "> with vanity prefix: <" + vanityPrefix + ">", e);
throw e;
}
} else
identity = identities.get(key);
identity.setPublicName(publicName);
identity.setDescription(description);
identity.setPictureBase64(pictureBase64);
identity.setEmailAddress(emailAddress);
// update the identity config
if (config != null)
identity.loadConfig(config, "", false);
if (createNew)
identities.add(identity);
else
identities.identityUpdated(key);
// update the default identity
if (setDefault)
identities.setDefault(identity);
}
use of i2p.bote.crypto.CryptoImplementation in project i2p.i2p-bote by i2p.
the class Contact method sign.
/**
* Creates a signature over the byte array representation of the packet
* @param identity An email identity that matches the destination field
* @param keyUpdateHandler
* @throws PasswordException
* @throws GeneralSecurityException
*/
private void sign(EmailIdentity identity, KeyUpdateHandler keyUpdateHandler) throws GeneralSecurityException, PasswordException {
byte[] data = getDataToSign();
CryptoImplementation cryptoImpl = identity.getCryptoImpl();
PrivateKey privateSigningKey = identity.getPrivateSigningKey();
signature = cryptoImpl.sign(data, privateSigningKey, keyUpdateHandler);
}
use of i2p.bote.crypto.CryptoImplementation in project i2p.i2p-bote by i2p.
the class Email method verifySignature.
/**
* Verifies that the <code>SIGNATURE_HEADER</code> header field
* contains a valid signature.<br/>
* The <code>SIGNATURE_VALID_HEADER</code> header field must not be
* present when this method is called.
* @return <code>true</code> if the signature is valid; <code>false</code>
* if it is invalid or missing, or an error occurred.
*/
private boolean verifySignature() {
String[] signatureHeaders;
try {
signatureHeaders = getHeader(SIGNATURE_HEADER);
} catch (MessagingException e) {
log.error("Cannot get header field: " + SIGNATURE_HEADER, e);
return false;
}
if (signatureHeaders == null || signatureHeaders.length <= 0)
return false;
String signatureHeader = signatureHeaders[0];
String unfoldedSignatureHeader = unfoldSignature(signatureHeader);
// the crypto implementation ID is the number before the underscore
int _index = unfoldedSignatureHeader.indexOf('_');
if (_index < 0)
return false;
String cryptoImplIdString = unfoldedSignatureHeader.substring(0, _index);
int cryptoImplId = 0;
try {
cryptoImplId = Integer.valueOf(cryptoImplIdString);
} catch (NumberFormatException e) {
return false;
}
CryptoImplementation cryptoImpl = CryptoFactory.getInstance(cryptoImplId);
// the actual signature is everything after the underscore
String base64Signature = unfoldedSignatureHeader.substring(_index + 1);
try {
// remove the signature before verifying
removeHeader(SIGNATURE_HEADER);
byte[] signature = Base64.decode(base64Signature);
EmailDestination senderDestination = new EmailDestination(getOneFromAddress());
return cryptoImpl.verify(toByteArray(), signature, senderDestination.getPublicSigningKey());
} catch (Exception e) {
log.error("Cannot verify email signature. Email: [" + this + "]", e);
return false;
} finally {
try {
setHeader(SIGNATURE_HEADER, signatureHeader);
} catch (MessagingException e) {
log.error("Cannot set signature header field.", e);
return false;
}
}
}
use of i2p.bote.crypto.CryptoImplementation in project i2p.i2p-bote by i2p.
the class Email method sign.
/**
* Creates a digital signature of the email and stores it in the
* <code>SIGNATURE_HEADER</code> header field. It also removes the
* <code>SIGNATURE_VALID_HEADER</code> header. If there is a signature
* already, it is replaced.<br/>
* The signature is computed over the stream representation of the
* email, minus the signature header if it is present.<br/>
* The signature includes the ID number of the {@link CryptoImplementation}
* used (signature lengths can be different for the same algorithm).
* @param senderIdentity
* @param keyUpdateHandler Needed for updating the signature key after signing (see {@link CryptoImplementation#sign(byte[], PrivateKey, KeyUpdateHandler)})
* @throws MessagingException
* @throws GeneralSecurityException
* @throws PasswordException
*/
public void sign(EmailIdentity senderIdentity, KeyUpdateHandler keyUpdateHandler) throws MessagingException, GeneralSecurityException, PasswordException {
// make sure there is no existing signature which would make the new signature invalid
removeHeader(SIGNATURE_HEADER);
// remove the signature validity flag before signing
removeHeader(SIGNATURE_VALID_HEADER);
CryptoImplementation cryptoImpl = senderIdentity.getCryptoImpl();
PrivateKey privateSigningKey = senderIdentity.getPrivateSigningKey();
byte[] signature = cryptoImpl.sign(toByteArray(), privateSigningKey, keyUpdateHandler);
String foldedSignature = foldSignature(cryptoImpl.getId() + "_" + Base64.encode(signature));
setHeader(SIGNATURE_HEADER, foldedSignature);
}
use of i2p.bote.crypto.CryptoImplementation in project i2p.i2p-bote by i2p.
the class EmailDestination method extractBase64Dest.
/**
* Looks for a Base64-encoded Email Destination in a string. Returns
* the Base64 encoding, or <code>null</code> if nothing is found.
* Even if the return value is non-<code>null</code>, it is not
* guaranteed to be a valid Email Destination.
* @param address
*/
public static String extractBase64Dest(String address) {
if (address == null)
return null;
// remove spaces and newlines
// doesn't affect extraction from "name <dest>" addresses
address.replaceAll("[\\s\\r\\n]+", "");
// remove possible prefixes
if (address.startsWith("mailto:") || address.startsWith("i2pbote:") || address.startsWith("bote:"))
address = address.substring(address.indexOf(':') + 1);
// find the crypto implementation for this key length
for (CryptoImplementation cryptoImpl : CryptoFactory.getInstances()) {
// length of an email destination with this CryptoImplementation
int base64Length = cryptoImpl.getBase64PublicKeyPairLength();
if (address.length() == base64Length)
return address;
// Check if the string contains base64Length chars in angle brackets
int ltIndex = address.indexOf('<');
int gtIndex = address.indexOf('>', ltIndex);
if (ltIndex >= 0 && ltIndex + base64Length + 1 == gtIndex)
return address.substring(ltIndex + 1, gtIndex);
// Check if the string is of the form EmailDest@foo
if (address.indexOf('@') == base64Length)
return address.substring(0, base64Length + 1);
}
return null;
}
Aggregations