1 package civitas.bboard.server;
2
3 import static org.junit.jupiter.api.Assertions.assertTrue;
4
5 import java.io.File;
6 import java.io.IOException;
7 import java.security.KeyStore;
8 import java.security.KeyStoreException;
9 import java.security.NoSuchAlgorithmException;
10 import java.security.PublicKey;
11 import java.security.UnrecoverableKeyException;
12 import java.security.cert.CertificateException;
13 import java.security.interfaces.RSAPublicKey;
14 import java.util.HashMap;
15 import java.util.List;
16 import java.util.Map;
17
18 import org.bouncycastle.crypto.CryptoException;
19 import org.junit.jupiter.api.DisplayName;
20 import org.junit.jupiter.api.Tag;
21 import org.junit.jupiter.api.Test;
22 import org.springframework.beans.factory.annotation.Autowired;
23 import org.springframework.boot.test.context.SpringBootTest;
24 import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
25 import org.springframework.boot.test.web.server.LocalServerPort;
26
27 import civitas.bboard.common.BBPostTestData;
28 import civitas.bboard.server.controllers.GetRestTemplate;
29 import civitas.bboard.server.controllers.NewBoardController;
30 import civitas.bboard.server.controllers.PostController;
31 import civitas.bboard.server.controllers.PostDTO;
32 import civitas.bboard.server.controllers.RequestParticipationController;
33 import civitas.bboard.server.controllers.RequestParticipationDTO;
34 import civitas.common.Configuration;
35 import civitas.common.GetPrivateKey;
36 import civitas.common.ServerHost;
37 import civitas.common.ServerRole;
38 import civitas.common.board.BulletinBoardTestData;
39 import civitas.common.election.ElectionDetailsTestData;
40 import civitas.crypto.CryptoBase;
41 import civitas.crypto.rsapublickey.ConvertPublicKeyToString;
42 import civitas.crypto.rsapublickey.PublicKeyTestData;
43 import civitas.crypto.signature.SignWithPublicKey;
44 import civitas.crypto.signature.Signature;
45
46 @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
47 class EndToEndTest implements BulletinBoardTestData, BBPostTestData, ElectionDetailsTestData, PublicKeyTestData {
48 @LocalServerPort
49 private int port;
50
51 @Autowired
52 GetRestTemplate getRestTemplate;
53
54 @Autowired
55 SignWithPublicKey signWithPublicKey;
56
57 @Autowired
58 CryptoBase cryptoBase;
59
60 @Autowired
61 PostController postController;
62
63 @Autowired
64 NewBoardController newBoardController;
65
66 @Autowired
67 RequestParticipationController requestParticipationController;
68
69 @Autowired
70 Configuration configuration;
71
72 @Autowired
73 GetPrivateKey getPrivateKey;
74
75 @Autowired
76 ConvertPublicKeyToString convertPublicKeyToString;
77
78 private RSAPublicKey supervisorPub;
79
80 private java.security.PrivateKey supervisorPriv;
81
82 private Map<String, PublicKey> keys;
83
84 private Map<String, String> keyStrings;
85
86 @Test
87 @Tag("endtoend")
88 @DisplayName("starting an election and posting to the board related to it")
89 void testPost() throws Exception {
90 Long startTime = System.currentTimeMillis();
91 String urlBase = "http://localhost:" + port;
92 getTestKeys();
93 String boardId = getRestTemplate
94 .apply()
95 .postForObject(urlBase + "/requestParticipation", createRequestParticipationDTO(), String.class);
96
97 String url = urlBase + "/boards/" + boardId;
98 Long actual = getRestTemplate.apply().postForObject(url, createPostDTO(), Long.class);
99 long endTime = System.currentTimeMillis();
100 assertTrue(actual >= startTime && actual <= endTime);
101 }
102
103 public PostDTO createPostDTO() throws CryptoException {
104 Signature signature =
105 signWithPublicKey.apply(supervisorPriv, supervisorPub, BOARD_CLOSED_CONTENT_COMMITMENT_XML.getBytes());
106 return new PostDTO(BOARD_CLOSED_CONTENT_COMMITMENT_META, BOARD_CLOSED_CONTENT_COMMITMENT_XML, signature);
107 }
108
109 public RequestParticipationDTO createRequestParticipationDTO() {
110 List<ServerHost> tellerDetails = List.of(
111 new ServerHost(ServerRole.BBS, "https://localhost/", keyStrings.get("bbs")),
112 new ServerHost(
113 ServerRole.TABULATION_TELLER, "https://localhost:" + port + "/", keyStrings.get("tabteller")),
114 new ServerHost(
115 ServerRole.REGISTRATION_TELLER,
116 "https://localhost:" + port + "/",
117 keyStrings.get("regteller")));
118 return RequestParticipationDTO.builder()
119 .electionID(ELECTION_ID_STRING)
120 .supervisorPubkey(PUBLIC_KEY_BASE64)
121 .registrarPubKey(PUBLIC_KEY2_BASE64)
122 .name(ELECTION_NAME)
123 .description(ELECTION_DESCRIPTION)
124 .version(VERSIONSTRING)
125 .ballotDesign(BALLOTDESIGN)
126 .startTime(START_TIME)
127 .stopTime(STOP_TIME)
128 .finalizeTime(FINALIZE_TIME)
129 .elGamalP(BIGINT_P.i)
130 .elGamalQ(BIGINT_Q.i)
131 .elGamalG(BIGINT_G.i)
132 .sharedKeyLength(KEYSIZE)
133 .nonceLength(NONCE_LENGTH)
134 .voterAnonymityParam(BLOCKSIZE)
135 .tellerDetails(tellerDetails)
136 .build();
137 }
138
139 public void getTestKeys()
140 throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException,
141 UnrecoverableKeyException {
142 char[] pwdArray = "test12345".toCharArray();
143 KeyStore store = KeyStore.getInstance(new File("lib/server.jks"), pwdArray);
144 supervisorPriv = (java.security.PrivateKey) store.getKey("supervisor", pwdArray);
145 keys = new HashMap<>();
146 keyStrings = new HashMap<>();
147
148 for (String name : List.of(
149 "supervisor", "registrar", "bbs", "regteller", "tabteller", "user1", "user2", "user3", "user4")) {
150 PublicKey publicKey = store.getCertificate(name).getPublicKey();
151 keys.put(name, publicKey);
152 keyStrings.put(name, convertPublicKeyToString.apply(publicKey));
153 }
154 supervisorPub = (RSAPublicKey) keys.get("supervisor");
155 }
156 }