4343import eu .europa .ec .dgc .issuance .restapi .dto .EgdcCodeData ;
4444import eu .europa .ec .dgc .issuance .restapi .dto .IssueData ;
4545import eu .europa .ec .dgc .issuance .restapi .dto .SignatureData ;
46- import java .io .ByteArrayOutputStream ;
47- import java .io .IOException ;
46+ import java .nio .charset .StandardCharsets ;
4847import java .security .InvalidKeyException ;
4948import java .security .KeyFactory ;
5049import java .security .MessageDigest ;
5453import java .security .SignatureException ;
5554import java .security .spec .InvalidKeySpecException ;
5655import java .security .spec .X509EncodedKeySpec ;
56+ import java .time .Duration ;
5757import java .time .ZonedDateTime ;
5858import java .time .temporal .ChronoUnit ;
5959import java .util .ArrayList ;
@@ -140,12 +140,12 @@ public SignatureData finishDgci(long dgciId, IssueData issueData) throws Excepti
140140 Optional <DgciEntity > dgciEntityOpt = dgciRepository .findById (dgciId );
141141 if (dgciEntityOpt .isPresent ()) {
142142 var dgciEntity = dgciEntityOpt .get ();
143- String signatureBase64 = certificateService .signHash (issueData .getHash ());
144143 String tan = tanService .generateNewTan ();
145144 dgciEntity .setHashedTan (tanService .hashTan (tan ));
146- dgciEntity .setCertHash (signatureBase64 );
145+ dgciEntity .setCertHash (issueData . getHash () );
147146 dgciRepository .saveAndFlush (dgciEntity );
148147 log .info ("signed for " + dgciId );
148+ String signatureBase64 = certificateService .signHash (issueData .getHash ());
149149 return new SignatureData (tan , signatureBase64 );
150150 } else {
151151 log .warn ("can not find dgci with id " + dgciId );
@@ -180,10 +180,11 @@ public DidDocument getDidDocument(String hash) {
180180
181181 /**
182182 * compute cose sign hash.
183+ *
183184 * @param coseMessage cose message
184185 * @return hash value
185186 */
186- public byte [] computeCoseSignHash (byte [] coseMessage ) {
187+ public byte [] computeCoseSignHash (byte [] coseMessage ) {
187188 try {
188189 CBORObject coseForSign = CBORObject .NewArray ();
189190 CBORObject cborCose = CBORObject .DecodeFromBytes (coseMessage );
@@ -212,11 +213,11 @@ public ClaimResponse claimUpdate(ClaimRequest claimRequest) {
212213 }
213214
214215 /**
215- * TODO: Add Comment.
216+ * claim dgci to wallet app.
217+ * means bind dgci with some public key from wallet app
218+ * @param claimRequest claim request
216219 */
217- public void claim (ClaimRequest claimRequest )
218- throws IOException , NoSuchAlgorithmException , SignatureException ,
219- InvalidKeySpecException , InvalidKeyException {
220+ public void claim (ClaimRequest claimRequest ) {
220221 if (!verifySignature (claimRequest )) {
221222 throw new WrongRequest ("signature verification failed" );
222223 }
@@ -237,6 +238,11 @@ public void claim(ClaimRequest claimRequest)
237238 dgciRepository .saveAndFlush (dgciEntity );
238239 throw new WrongRequest ("tan mismatch" );
239240 }
241+ ZonedDateTime tanExpireTime = dgciEntity .getCreatedAt ()
242+ .plus (Duration .ofHours (issuanceConfigProperties .getTanExpirationHours ()));
243+ if (tanExpireTime .isBefore (ZonedDateTime .now ())) {
244+ throw new WrongRequest ("tan expired" );
245+ }
240246 dgciEntity .setClaimed (true );
241247 dgciEntity .setRetryCounter (dgciEntity .getRetryCounter () + 1 );
242248 dgciEntity .setPublicKey (claimRequest .getPublicKey ().getValue ());
@@ -249,26 +255,47 @@ public void claim(ClaimRequest claimRequest)
249255 }
250256 }
251257
252- private boolean verifySignature (ClaimRequest claimRequest )
253- throws IOException , NoSuchAlgorithmException , SignatureException ,
254- InvalidKeyException , InvalidKeySpecException {
255- ByteArrayOutputStream bos = new ByteArrayOutputStream ();
256- bos .write (claimRequest .getDgci ().getBytes ());
257- bos .write (Base64 .getDecoder ().decode (claimRequest .getTanHash ()));
258+ private boolean verifySignature (ClaimRequest claimRequest ) {
258259 byte [] keyBytes = Base64 .getDecoder ().decode (claimRequest .getPublicKey ().getValue ());
259- bos .write (keyBytes );
260260 X509EncodedKeySpec spec = new X509EncodedKeySpec (keyBytes );
261- KeyFactory kf = KeyFactory .getInstance (claimRequest .getPublicKey ().getType ());
262- PublicKey publicKey = kf .generatePublic (spec );
263- Signature signature = Signature .getInstance (claimRequest .getSigAlg ());
264- signature .initVerify (publicKey );
265- signature .update (bos .toByteArray ());
266- byte [] sigBytes = Base64 .getDecoder ().decode (claimRequest .getSignature ());
267- return signature .verify (sigBytes );
261+ KeyFactory kf ;
262+ try {
263+ kf = KeyFactory .getInstance (claimRequest .getPublicKey ().getType ());
264+ } catch (NoSuchAlgorithmException e ) {
265+ throw new WrongRequest ("key type not supported: '" + claimRequest .getPublicKey ().getType ()
266+ + "', try RSA or EC" );
267+ }
268+ PublicKey publicKey ;
269+ try {
270+ publicKey = kf .generatePublic (spec );
271+ } catch (InvalidKeySpecException e ) {
272+ throw new WrongRequest ("invalid key" );
273+ }
274+ Signature signature ;
275+ try {
276+ signature = Signature .getInstance (claimRequest .getSigAlg ());
277+ } catch (NoSuchAlgorithmException e ) {
278+ throw new WrongRequest ("signature algorithm not supported: '" + claimRequest .getSigAlg () + "'" );
279+ }
280+ StringBuilder dataToSign = new StringBuilder ();
281+ dataToSign .append (claimRequest .getTanHash ())
282+ .append (claimRequest .getCertHash ())
283+ .append (claimRequest .getPublicKey ().getValue ());
284+ try {
285+ signature .initVerify (publicKey );
286+ signature .update (dataToSign .toString ().getBytes (StandardCharsets .UTF_8 ));
287+ byte [] sigBytes = Base64 .getDecoder ().decode (claimRequest .getSignature ());
288+ return signature .verify (sigBytes );
289+ } catch (InvalidKeyException e ) {
290+ throw new WrongRequest ("invalid key for signature" );
291+ } catch (SignatureException e ) {
292+ throw new WrongRequest ("can not validity signature" , e );
293+ }
268294 }
269295
270296 /**
271297 * Create edgc in backend.
298+ *
272299 * @param eudgc certificate
273300 * @return edgc qr code and tan
274301 */
0 commit comments