1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package io.github.tonywasher.joceanus.gordianknot.api.encrypt;
18
19 import io.github.tonywasher.joceanus.gordianknot.api.digest.GordianDigestSpec;
20 import io.github.tonywasher.joceanus.gordianknot.api.digest.GordianDigestType;
21 import io.github.tonywasher.joceanus.gordianknot.api.keypair.GordianKeyPairType;
22
23 import java.util.Iterator;
24 import java.util.List;
25 import java.util.Objects;
26
27
28
29
30 public final class GordianEncryptorSpec {
31
32
33
34 private static final String ECELGAMAL = "ElGamal";
35
36
37
38
39 static final String SEP = "-";
40
41
42
43
44 private final GordianKeyPairType theKeyPairType;
45
46
47
48
49 private final Object theEncryptorType;
50
51
52
53
54 private final boolean isValid;
55
56
57
58
59 private String theName;
60
61
62
63
64
65
66
67 public GordianEncryptorSpec(final GordianKeyPairType pKeyPairType,
68 final Object pEncryptorType) {
69 theKeyPairType = pKeyPairType;
70 theEncryptorType = pEncryptorType;
71 isValid = checkValidity();
72 }
73
74
75
76
77
78
79 public GordianKeyPairType getKeyPairType() {
80 return theKeyPairType;
81 }
82
83
84
85
86
87
88 public Object getEncryptorType() {
89 return theEncryptorType;
90 }
91
92
93
94
95
96
97 public GordianDigestSpec getDigestSpec() {
98 if (theEncryptorType instanceof GordianDigestSpec mySpec) {
99 return mySpec;
100 }
101 throw new IllegalArgumentException();
102 }
103
104
105
106
107
108
109 public GordianSM2EncryptionSpec getSM2EncryptionSpec() {
110 if (theEncryptorType instanceof GordianSM2EncryptionSpec mySpec) {
111 return mySpec;
112 }
113 throw new IllegalArgumentException();
114 }
115
116
117
118
119
120
121 @SuppressWarnings("unchecked")
122 public Iterator<GordianEncryptorSpec> encryptorSpecIterator() {
123 if (theEncryptorType instanceof List) {
124 return ((List<GordianEncryptorSpec>) theEncryptorType).iterator();
125 }
126 throw new IllegalArgumentException();
127 }
128
129
130
131
132
133
134 public boolean isValid() {
135 return isValid;
136 }
137
138
139
140
141
142
143 private boolean checkValidity() {
144 if (theKeyPairType == null) {
145 return false;
146 }
147 switch (theKeyPairType) {
148 case RSA:
149 case ELGAMAL:
150 return theEncryptorType instanceof GordianDigestSpec s
151 && s.isValid();
152 case SM2:
153 return theEncryptorType == null
154 || (theEncryptorType instanceof GordianSM2EncryptionSpec s
155 && s.isValid());
156 case EC:
157 case GOST2012:
158 return theEncryptorType == null;
159 case COMPOSITE:
160 return theEncryptorType instanceof List && checkComposite();
161 default:
162 return false;
163 }
164 }
165
166
167
168
169
170
171 public boolean isSupported() {
172 switch (theKeyPairType) {
173 case RSA:
174 case ELGAMAL:
175 final GordianDigestSpec mySpec = getDigestSpec();
176 return GordianDigestType.SHA2.equals(mySpec.getDigestType()) && !mySpec.isSha2Hybrid();
177 case EC:
178 case GOST2012:
179 case SM2:
180 case COMPOSITE:
181 return true;
182 default:
183 return false;
184 }
185 }
186
187
188
189
190
191
192 private boolean checkComposite() {
193 final Iterator<GordianEncryptorSpec> myIterator = encryptorSpecIterator();
194 while (myIterator.hasNext()) {
195
196 final GordianEncryptorSpec mySpec = myIterator.next();
197 if (mySpec == null || !mySpec.isValid()) {
198 return false;
199 }
200 }
201 return true;
202 }
203
204 @Override
205 public String toString() {
206
207 if (theName == null) {
208
209 if (isValid) {
210
211 theName = theKeyPairType.toString();
212 switch (theKeyPairType) {
213 case RSA:
214 case ELGAMAL:
215 theName += SEP + theEncryptorType;
216 break;
217 case EC:
218 case GOST2012:
219 theName += SEP + ECELGAMAL;
220 break;
221 case SM2:
222 theName += SEP + (theEncryptorType == null ? ECELGAMAL : theEncryptorType);
223 break;
224 case COMPOSITE:
225 final Iterator<GordianEncryptorSpec> myIterator = encryptorSpecIterator();
226 final StringBuilder myBuilder = new StringBuilder(theName);
227 while (myIterator.hasNext()) {
228 myBuilder.append(SEP).append(myIterator.next().toString());
229 }
230 theName = myBuilder.toString();
231 break;
232 default:
233 break;
234 }
235 } else {
236
237 theName = "InvalidEncryptorSpec: " + theKeyPairType + ":" + theEncryptorType;
238 }
239 }
240
241
242 return theName;
243 }
244
245 @Override
246 public boolean equals(final Object pThat) {
247
248 if (this == pThat) {
249 return true;
250 }
251 if (pThat == null) {
252 return false;
253 }
254
255
256 return pThat instanceof GordianEncryptorSpec myThat
257 && theKeyPairType == myThat.getKeyPairType()
258 && Objects.equals(theEncryptorType, myThat.theEncryptorType);
259 }
260
261 @Override
262 public int hashCode() {
263 return Objects.hash(theKeyPairType, theEncryptorType);
264 }
265 }