Skip to content

Commit 727b685

Browse files
Add support for the BC-FIPS jar with tests (#14)
* Add support for the BC-FIPS jar with tests * Missed pom module declaration * more dependency wrangling * Add test for code coverage of exception handling * Improve test comment
1 parent cad984c commit 727b685

10 files changed

Lines changed: 453 additions & 14 deletions

File tree

coverage/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@
5858
<artifactId>jpaseto-its-sodium-jackson</artifactId>
5959
<scope>test</scope>
6060
</dependency>
61+
<dependency>
62+
<groupId>dev.paseto</groupId>
63+
<artifactId>jpaseto-its-fips</artifactId>
64+
<scope>test</scope>
65+
</dependency>
6166
</dependencies>
6267

6368
<build>

fips-integration-tests/README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# jpaseto-its-fips
2+
3+
This test module contains a set of tests for validating that jpaseto works with the Bouncy Castle
4+
FIPS (Federal Information Processing Standard) library. These tests require a separate module because the BC-FIPS
5+
jar and regular BC jars cannot both be depended on in the same module
6+
([it causes a runtime error when adding the BC-FIPS provider](https://stackoverflow.com/questions/60930130/intellij-gradle-unable-to-find-method-org-bouncycastle-crypto-cryptoservicesre)).
7+
8+
Currently, we only have validation for the v1.public specification.
9+
10+
Note that the FIPS standard currently does not support the Ed25519 signature algorithm, so there are no tests here
11+
to validate that v2.public tokens can be generated while using the BC-FIPS jar. When Ed25519 is added to the standard,
12+
tests can be added here to validate that jpaseto operates properly in BC-FIPS approved mode.

fips-integration-tests/pom.xml

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
~ Copyright 2019-Present paseto.dev, Inc.
4+
~
5+
~ Licensed under the Apache License, Version 2.0 (the "License");
6+
~ you may not use this file except in compliance with the License.
7+
~ You may obtain a copy of the License at
8+
~
9+
~ http://www.apache.org/licenses/LICENSE-2.0
10+
~
11+
~ Unless required by applicable law or agreed to in writing, software
12+
~ distributed under the License is distributed on an "AS IS" BASIS,
13+
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
~ See the License for the specific language governing permissions and
15+
~ limitations under the License.
16+
-->
17+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
18+
<modelVersion>4.0.0</modelVersion>
19+
20+
<parent>
21+
<groupId>dev.paseto</groupId>
22+
<artifactId>jpaseto-root</artifactId>
23+
<version>0.5.1-SNAPSHOT</version>
24+
</parent>
25+
26+
<artifactId>jpaseto-its-fips</artifactId>
27+
<name>JPaseto :: ITs :: FIPS</name>
28+
29+
<dependencies>
30+
<dependency>
31+
<groupId>dev.paseto</groupId>
32+
<artifactId>jpaseto-api</artifactId>
33+
</dependency>
34+
<dependency>
35+
<groupId>dev.paseto</groupId>
36+
<artifactId>jpaseto-impl</artifactId>
37+
</dependency>
38+
<dependency>
39+
<groupId>org.bouncycastle</groupId>
40+
<artifactId>bc-fips</artifactId>
41+
<version>1.0.2</version>
42+
<scope>runtime</scope>
43+
</dependency>
44+
<dependency>
45+
<groupId>dev.paseto</groupId>
46+
<artifactId>jpaseto-hkdf</artifactId>
47+
<scope>runtime</scope>
48+
</dependency>
49+
<dependency>
50+
<groupId>dev.paseto</groupId>
51+
<artifactId>jpaseto-jackson</artifactId>
52+
<scope>runtime</scope>
53+
</dependency>
54+
</dependencies>
55+
</project>
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*
2+
* Copyright 2019-Present paseto.dev, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package dev.paseto.jpaseto.fips.its
17+
18+
import dev.paseto.jpaseto.Paseto
19+
import org.hamcrest.Description
20+
import org.hamcrest.TypeSafeMatcher
21+
22+
class PasetoMatcher extends TypeSafeMatcher<Paseto> {
23+
24+
private final Paseto expected
25+
26+
PasetoMatcher(Paseto expected) {
27+
this.expected = expected
28+
}
29+
30+
@Override
31+
protected boolean matchesSafely(Paseto actual) {
32+
return expected.equals(actual)
33+
}
34+
35+
@Override
36+
void describeTo(Description description) {
37+
description.appendText("token with:")
38+
.appendText("\n\t\tversion: ").appendValue(expected.version)
39+
.appendText("\n\t\tpurpose: ").appendValue(expected.purpose)
40+
.appendText("\n\t\tpayload: ").appendValue(expected.claims?.entrySet())
41+
.appendText("\n\t\tfooter: ")
42+
.appendText("\n\t\t\tvalue: ").appendValue(expected.footer?.value())
43+
.appendText("\n\t\t\tclaims: ").appendValue(expected.footer?.entrySet())
44+
}
45+
46+
@Override
47+
protected void describeMismatchSafely(Paseto item, Description mismatchDescription) {
48+
mismatchDescription.appendText( "was token with:")
49+
mismatchDescription.appendText("\n\t\tversion: ").appendValue(item.version)
50+
if (expected.version != item.version) {
51+
mismatchDescription.appendText(" << does not match")
52+
}
53+
mismatchDescription.appendText("\n\t\tpurpose: ").appendValue(item.purpose)
54+
if (expected.purpose != item.purpose) {
55+
mismatchDescription.appendText(" << does not match")
56+
}
57+
mismatchDescription.appendText("\n\t\tpayload: ").appendValue(item.claims?.entrySet())
58+
if (expected.claims != item.claims) {
59+
mismatchDescription.appendText(" << does not match")
60+
}
61+
mismatchDescription.appendText("\n\t\tfooter: ")
62+
if (expected.footer != item.footer) {
63+
mismatchDescription.appendText(" << does not match")
64+
}
65+
66+
if (item.footer != null) {
67+
mismatchDescription.appendText("\n\t\t\tvalue: ").appendValue(item.footer.value())
68+
if (expected.footer == null || item.footer.value() != expected.footer.value()) {
69+
mismatchDescription.appendText(" << does not match")
70+
}
71+
mismatchDescription.appendText("\n\t\t\tclaims: ").appendValue(item.footer.entrySet())
72+
if (expected.footer == null || item.footer.claims != expected.footer.claims) {
73+
mismatchDescription.appendText(" << does not match")
74+
}
75+
}
76+
}
77+
78+
static PasetoMatcher paseto(Paseto paseto) {
79+
return new PasetoMatcher(paseto)
80+
}
81+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Copyright 2019-Present paseto.dev, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package dev.paseto.jpaseto.fips.its
17+
18+
import dev.paseto.jpaseto.Paseto
19+
import dev.paseto.jpaseto.Purpose
20+
import dev.paseto.jpaseto.Version
21+
import dev.paseto.jpaseto.impl.DefaultClaims
22+
import dev.paseto.jpaseto.impl.DefaultFooterClaims
23+
import dev.paseto.jpaseto.impl.DefaultPaseto
24+
import org.testng.Assert
25+
26+
import java.time.Clock
27+
import java.time.Instant
28+
import java.time.ZoneOffset
29+
30+
class Util {
31+
static Paseto v1PublicFromClaims(Map<String, Object> claims, Map<String, Object> footerClaims) {
32+
return fromClaims(Version.V1, Purpose.PUBLIC, claims, footerClaims)
33+
}
34+
35+
static Paseto fromClaims(Version version, Purpose purpose, Map<String, Object> claims, Map<String, Object> footerClaims) {
36+
new DefaultPaseto(version, purpose, new DefaultClaims(claims), new DefaultFooterClaims(footerClaims))
37+
}
38+
39+
static Clock clockForVectors() {
40+
return Clock.fixed(Instant.ofEpochMilli(1544490000000), ZoneOffset.UTC) // December 11, 2018 01:00:00
41+
}
42+
43+
static <T extends Throwable> T expect(Class<T> catchMe, Closure closure) {
44+
try {
45+
closure.call()
46+
Assert.fail("Expected ${catchMe.getName()} to be thrown.")
47+
} catch(e) {
48+
if (!e.class.isAssignableFrom(catchMe)) {
49+
throw e
50+
}
51+
return e
52+
}
53+
}
54+
}

0 commit comments

Comments
 (0)