1 /****************************************************************
2 * Licensed to the Apache Software Foundation (ASF) under one *
3 * or more contributor license agreements. See the NOTICE file *
4 * distributed with this work for additional information *
5 * regarding copyright ownership. The ASF licenses this file *
6 * to you under the Apache License, Version 2.0 (the *
7 * "License"); you may not use this file except in compliance *
8 * with the License. You may obtain a copy of the License at *
9 * *
10 * http://www.apache.org/licenses/LICENSE-2.0 *
11 * *
12 * Unless required by applicable law or agreed to in writing, *
13 * software distributed under the License is distributed on an *
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
15 * KIND, either express or implied. See the License for the *
16 * specific language governing permissions and limitations *
17 * under the License. *
18 ****************************************************************/
19
20 package org.apache.james.jdkim;
21
22 import java.io.ByteArrayInputStream;
23 import java.io.IOException;
24 import java.security.NoSuchAlgorithmException;
25 import java.security.PrivateKey;
26 import java.security.interfaces.RSAKey;
27 import java.security.spec.InvalidKeySpecException;
28 import java.util.List;
29 import java.util.Properties;
30
31 import javax.mail.Address;
32 import javax.mail.MessagingException;
33 import javax.mail.Session;
34 import javax.mail.Transport;
35 import javax.mail.internet.InternetAddress;
36 import javax.mail.internet.MimeMessage;
37
38 import junit.framework.TestCase;
39
40 import org.apache.james.jdkim.api.PublicKeyRecord;
41 import org.apache.james.jdkim.api.PublicKeyRecordRetriever;
42 import org.apache.james.jdkim.exceptions.FailException;
43 import org.apache.james.jdkim.exceptions.PermFailException;
44 import org.apache.james.jdkim.exceptions.TempFailException;
45 import org.apache.james.jdkim.impl.DNSPublicKeyRecordRetriever;
46 import org.apache.james.jdkim.tagvalue.SignatureRecordImpl;
47 import org.apache.james.jdkim.tagvalue.TagValue;
48 import org.apache.mailet.HostAddress;
49
50 import com.sun.mail.smtp.SMTPTransport;
51
52 public class DNSPublicKeyRetrieverTest extends TestCase {
53
54 public void testWrongOption() throws TempFailException {
55 try {
56 new DNSPublicKeyRecordRetriever().getRecords("somethingelse",
57 "test", "test");
58 fail("expected unsupported operation");
59 } catch (PermFailException e) {
60 e.printStackTrace();
61 }
62 }
63
64 public void testConstructor() {
65 new DNSPublicKeyRecordRetriever();
66 }
67
68 /**
69 * TODO: Requires internet connection
70 *
71 * @throws PermFailException
72 */
73 public void testRetrieve() throws TempFailException, PermFailException {
74 PublicKeyRecordRetriever pkr = new DNSPublicKeyRecordRetriever();
75 System.out.println(pkr.getRecords("dns/txt", "beta", "gmail.com"));
76 System.out
77 .println(pkr.getRecords("dns/txt", "lima", "yahoogroups.com"));
78
79 new TagValue((String) pkr.getRecords("dns/txt", "lima",
80 "yahoogroups.com").get(0));
81 }
82
83 public void testKeyPair() throws PermFailException, TempFailException,
84 NoSuchAlgorithmException, InvalidKeySpecException {
85 PublicKeyRecord key = new DKIMVerifier()
86 .publicKeySelector(new MockPublicKeyRecordRetriever(
87 "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDYDaYKXzwVYwqWbLhmuJ66aTAN8wmDR+rfHE8HfnkSOax0oIoTM5zquZrTLo30870YMfYzxwfB6j/Nz3QdwrUD/t0YMYJiUKyWJnCKfZXHJBJ+yfRHr7oW+UW3cVo9CG2bBfIxsInwYe175g9UjyntJpWueqdEIo1c2bhv9Mp66QIDAQAB;",
88 "dummy", "dummy").getRecords("dns/txt", "dummy",
89 "dummy"));
90
91 // String privateKey =
92 // "MIICXAIBAAKBgQDYDaYKXzwVYwqWbLhmuJ66aTAN8wmDR+rfHE8HfnkSOax0oIoTM5zquZrTLo30870YMfYzxwfB6j/Nz3QdwrUD/t0YMYJiUKyWJnCKfZXHJBJ+yfRHr7oW+UW3cVo9CG2bBfIxsInwYe175g9UjyntJpWueqdEIo1c2bhv9Mp66QIDAQABAoGBAI8XcwnZi0Sq5N89wF+gFNhnREFo3rsJDaCY8iqHdA5DDlnr3abb/yhipw0I/1HlgC6fIG2oexXOXFWl+USgqRt1kTt9jXhVFExg8mNko2UelAwFtsl8CRjVcYQOcedeH/WM/mXjg2wUqqZenBmlKlD6vNb70jFJeVaDJ/7n7j8BAkEA9NkH2D4Zgj/IOAVYccZYH74+VgO0e7VkUjQk9wtJ2j6cGqJ6Pfj0roVIMUWzoBb8YfErR8l6JnVQbfy83gJeiQJBAOHk3ow7JjAn8XuOyZx24KcTaYWKUkAQfRWYDFFOYQF4KV9xLSEtycY0kjsdxGKDudWcsATllFzXDCQF6DTNIWECQEA52ePwTjKrVnLTfCLEG4OgHKvlZud4amthwDyJWoMEH2ChNB2je1N4JLrABOE+hk+OuoKnKAKEjWd8f3Jg/rkCQHj8mQmogHqYWikgP/FSZl518jV48Tao3iXbqvU9Mo2T6yzYNCCqIoDLFWseNVnCTZ0Qb+IfiEf1UeZVV5o4J+ECQDatNnS3V9qYUKjj/krNRD/U0+7eh8S2ylLqD3RlSn9KtYGRMgAtUXtiOEizBH6bd/orzI9V9sw8yBz+ZqIH25Q=";
93 String privateKeyPKCS8 = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBANgNpgpfPBVjCpZsuGa4nrppMA3zCYNH6t8cTwd+eRI5rHSgihMznOq5mtMujfTzvRgx9jPHB8HqP83PdB3CtQP+3RgxgmJQrJYmcIp9lcckEn7J9Eevuhb5RbdxWj0IbZsF8jGwifBh7XvmD1SPKe0mla56p0QijVzZuG/0ynrpAgMBAAECgYEAjxdzCdmLRKrk3z3AX6AU2GdEQWjeuwkNoJjyKod0DkMOWevdptv/KGKnDQj/UeWALp8gbah7Fc5cVaX5RKCpG3WRO32NeFUUTGDyY2SjZR6UDAW2yXwJGNVxhA5x514f9Yz+ZeODbBSqpl6cGaUqUPq81vvSMUl5VoMn/ufuPwECQQD02QfYPhmCP8g4BVhxxlgfvj5WA7R7tWRSNCT3C0naPpwaono9+PSuhUgxRbOgFvxh8StHyXomdVBt/LzeAl6JAkEA4eTejDsmMCfxe47JnHbgpxNphYpSQBB9FZgMUU5hAXgpX3EtIS3JxjSSOx3EYoO51ZywBOWUXNcMJAXoNM0hYQJAQDnZ4/BOMqtWctN8IsQbg6Acq+Vm53hqa2HAPIlagwQfYKE0HaN7U3gkusAE4T6GT466gqcoAoSNZ3x/cmD+uQJAePyZCaiAephaKSA/8VJmXnXyNXjxNqjeJduq9T0yjZPrLNg0IKoigMsVax41WcJNnRBv4h+IR/VR5lVXmjgn4QJANq02dLdX2phQqOP+Ss1EP9TT7t6HxLbKUuoPdGVKf0q1gZEyAC1Re2I4SLMEfpt3+ivMj1X2zDzIHP5mogfblA==";
94
95 PrivateKey privKey = DKIMSigner.getPrivateKey(privateKeyPKCS8);
96
97 // controllo che il modulus della chiave privata corrisponda al record
98 // pubblico
99 assertEquals(((RSAKey) privKey).getModulus(), ((RSAKey) key
100 .getPublicKey()).getModulus());
101 }
102
103 public void testSignVerify() throws NoSuchAlgorithmException,
104 InvalidKeySpecException, IOException, FailException {
105 MockPublicKeyRecordRetriever mockPublicKeyRecordRetriever = new MockPublicKeyRecordRetriever(
106 "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDYDaYKXzwVYwqWbLhmuJ66aTAN8wmDR+rfHE8HfnkSOax0oIoTM5zquZrTLo30870YMfYzxwfB6j/Nz3QdwrUD/t0YMYJiUKyWJnCKfZXHJBJ+yfRHr7oW+UW3cVo9CG2bBfIxsInwYe175g9UjyntJpWueqdEIo1c2bhv9Mp66QIDAQAB;",
107 "selector", "example.com");
108 PublicKeyRecord key = new DKIMVerifier()
109 .publicKeySelector(mockPublicKeyRecordRetriever.getRecords(
110 "dns/txt", "selector", "example.com"));
111 String privateKeyPKCS8 = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBANgNpgpfPBVjCpZsuGa4nrppMA3zCYNH6t8cTwd+eRI5rHSgihMznOq5mtMujfTzvRgx9jPHB8HqP83PdB3CtQP+3RgxgmJQrJYmcIp9lcckEn7J9Eevuhb5RbdxWj0IbZsF8jGwifBh7XvmD1SPKe0mla56p0QijVzZuG/0ynrpAgMBAAECgYEAjxdzCdmLRKrk3z3AX6AU2GdEQWjeuwkNoJjyKod0DkMOWevdptv/KGKnDQj/UeWALp8gbah7Fc5cVaX5RKCpG3WRO32NeFUUTGDyY2SjZR6UDAW2yXwJGNVxhA5x514f9Yz+ZeODbBSqpl6cGaUqUPq81vvSMUl5VoMn/ufuPwECQQD02QfYPhmCP8g4BVhxxlgfvj5WA7R7tWRSNCT3C0naPpwaono9+PSuhUgxRbOgFvxh8StHyXomdVBt/LzeAl6JAkEA4eTejDsmMCfxe47JnHbgpxNphYpSQBB9FZgMUU5hAXgpX3EtIS3JxjSSOx3EYoO51ZywBOWUXNcMJAXoNM0hYQJAQDnZ4/BOMqtWctN8IsQbg6Acq+Vm53hqa2HAPIlagwQfYKE0HaN7U3gkusAE4T6GT466gqcoAoSNZ3x/cmD+uQJAePyZCaiAephaKSA/8VJmXnXyNXjxNqjeJduq9T0yjZPrLNg0IKoigMsVax41WcJNnRBv4h+IR/VR5lVXmjgn4QJANq02dLdX2phQqOP+Ss1EP9TT7t6HxLbKUuoPdGVKf0q1gZEyAC1Re2I4SLMEfpt3+ivMj1X2zDzIHP5mogfblA==";
112 PrivateKey privKey = DKIMSigner.getPrivateKey(privateKeyPKCS8);
113
114 // Check that the private key modulus equals the public key modulus
115 assertEquals(((RSAKey) privKey).getModulus(), ((RSAKey) key
116 .getPublicKey()).getModulus());
117
118 DKIMSigner signer = new DKIMSigner(
119 "v=1; s=selector; d=example.com; h=from:to; a=rsa-sha256; bh=; b=;",
120 privKey);
121 String message = "From: io@bago.org\r\nTo: io@bago.org\r\n\r\nbody\r\n";
122 String res = signer.sign(new ByteArrayInputStream(message.getBytes()));
123 System.out.println(res);
124 String signedMessage = res + "\r\n"
125 + "From: io@bago.org\r\nTo: io@bago.org\r\n\r\nbody\r\n";
126
127 new DKIMVerifier(mockPublicKeyRecordRetriever)
128 .verify(new ByteArrayInputStream(signedMessage.getBytes()));
129
130 }
131
132 /*
133 * public void testDONOTCOMMITME() throws NoSuchAlgorithmException,
134 * InvalidKeySpecException, IOException, FailException, MessagingException {
135 * List records = new DNSPublicKeyRecordRetriever().getRecords("dns/txt",
136 * "selector1", "emailsimulator.com"); PublicKeyRecord key = new
137 * DKIMVerifier().publicKeySelector(records);
138 * System.out.println(key.toString()); key.validate(); String
139 * privateKeyPKCS8 =
140 * "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBANgNpgpfPBVjCpZsuGa4nrppMA3zCYNH6t8cTwd+eRI5rHSgihMznOq5mtMujfTzvRgx9jPHB8HqP83PdB3CtQP+3RgxgmJQrJYmcIp9lcckEn7J9Eevuhb5RbdxWj0IbZsF8jGwifBh7XvmD1SPKe0mla56p0QijVzZuG/0ynrpAgMBAAECgYEAjxdzCdmLRKrk3z3AX6AU2GdEQWjeuwkNoJjyKod0DkMOWevdptv/KGKnDQj/UeWALp8gbah7Fc5cVaX5RKCpG3WRO32NeFUUTGDyY2SjZR6UDAW2yXwJGNVxhA5x514f9Yz+ZeODbBSqpl6cGaUqUPq81vvSMUl5VoMn/ufuPwECQQD02QfYPhmCP8g4BVhxxlgfvj5WA7R7tWRSNCT3C0naPpwaono9+PSuhUgxRbOgFvxh8StHyXomdVBt/LzeAl6JAkEA4eTejDsmMCfxe47JnHbgpxNphYpSQBB9FZgMUU5hAXgpX3EtIS3JxjSSOx3EYoO51ZywBOWUXNcMJAXoNM0hYQJAQDnZ4/BOMqtWctN8IsQbg6Acq+Vm53hqa2HAPIlagwQfYKE0HaN7U3gkusAE4T6GT466gqcoAoSNZ3x/cmD+uQJAePyZCaiAephaKSA/8VJmXnXyNXjxNqjeJduq9T0yjZPrLNg0IKoigMsVax41WcJNnRBv4h+IR/VR5lVXmjgn4QJANq02dLdX2phQqOP+Ss1EP9TT7t6HxLbKUuoPdGVKf0q1gZEyAC1Re2I4SLMEfpt3+ivMj1X2zDzIHP5mogfblA==";
141 * PrivateKey privKey = DKIMSigner.getPrivateKey(privateKeyPKCS8);
142 * // Check that the private key modulus equals the public key modulus
143 * assertEquals(((RSAKey) privKey).getModulus(), ((RSAKey)
144 * key.getPublicKey()).getModulus());
145 * // NOTE: this works both with "b=;" and "b=" but not with WSP/FWS after
146 * the b=". DKIMSigner signer = new DKIMSigner("v=1; c=simple/simple;
147 * s=selector1; d=emailsimulator.com; h=from:to:message-id:date; a=rsa-sha1;
148 * bh=; b=;", privKey); String message ="Date: Thu, 1 Oct 2009 17:15:28
149 * +0200 (CEST)\r\nFrom: <io@bago.org>\r\nMessage-Id:
150 * <test4325223452@localhost>\r\nSubject: prova11 bago.org\r\nTo:
151 * <vidocq@gmail.com>\r\n\r\nbody text\r\n"; String res = signer.sign(new
152 * ByteArrayInputStream(message.getBytes())); System.out.println(res);
153 * String signedMessage =res+"\r\n"+message;
154 *
155 * new DKIMVerifier().verify(new
156 * ByteArrayInputStream(signedMessage.getBytes()));
157 *
158 * System.out.println("-------------------------"); Properties props = new
159 * Properties(); props.put("mail.smtp.from", "io@bago.org"); Session session =
160 * Session.getDefaultInstance(props); MimeMessage m = new
161 * MimeMessage(session, new ByteArrayInputStream(signedMessage.getBytes()));
162 * m.writeTo(System.out);
163 *
164 * HostAddress ha = new HostAddress("vm3.void.it", "smtp://94.23.67.198");
165 * Transport transport = session.getTransport(ha);
166 * transport.connect("vm3.void.it", 6025, "bago", "bv678nt"); Address[]
167 * recipients = new Address[] { new InternetAddress("vidocq@gmail.com"), new
168 * InternetAddress("bago@ngi.it") }; transport.sendMessage(m, recipients);
169 * transport.close();
170 * }
171 */
172
173 }