@@ -290,6 +290,7 @@ def decode(
290290 keys : Union [COSEKeyInterface , List [COSEKeyInterface ]],
291291 context : Optional [Union [Dict [str , Any ], List [Any ]]] = None ,
292292 external_aad : bytes = b"" ,
293+ detached_payload : Optional [bytes ] = None ,
293294 ) -> bytes :
294295 """
295296 Verifies and decodes COSE data, and returns only payload.
@@ -303,14 +304,15 @@ def decode(
303304 structure for key deriviation functions.
304305 external_aad(bytes): External additional authenticated data supplied by
305306 application.
307+ detached_payload (Optional[bytes]): The detached payload that should be verified with data.
306308 Returns:
307309 bytes: A byte string of decoded payload.
308310 Raises:
309311 ValueError: Invalid arguments.
310312 DecodeError: Failed to decode data.
311313 VerifyError: Failed to verify data.
312314 """
313- _ , _ , res = self .decode_with_headers (data , keys , context , external_aad )
315+ _ , _ , res = self .decode_with_headers (data , keys , context , external_aad , detached_payload )
314316 return res
315317
316318 def decode_with_headers (
@@ -319,6 +321,7 @@ def decode_with_headers(
319321 keys : Union [COSEKeyInterface , List [COSEKeyInterface ]],
320322 context : Optional [Union [Dict [str , Any ], List [Any ]]] = None ,
321323 external_aad : bytes = b"" ,
324+ detached_payload : Optional [bytes ] = None ,
322325 ) -> Tuple [Dict [int , Any ], Dict [int , Any ], bytes ]:
323326 """
324327 Verifies and decodes COSE data, and returns protected headers, unprotected headers and payload.
@@ -332,6 +335,7 @@ def decode_with_headers(
332335 structure for key deriviation functions.
333336 external_aad(bytes): External additional authenticated data supplied by
334337 application.
338+ detached_payload (Optional[bytes]): The detached payload that should be verified with data.
335339 Returns:
336340 Tuple[Dict[int, Any], Dict[int, Any], bytes]: A dictionary data of decoded protected headers, and a dictionary data of unprotected headers, and a byte string of decoded payload.
337341 Raises:
@@ -376,6 +380,14 @@ def decode_with_headers(
376380 else :
377381 raise ValueError (f"Unsupported or unknown CBOR tag({ data .tag } )." )
378382
383+ payload = data .value [2 ]
384+ if detached_payload is not None :
385+ if data .value [2 ] is not None :
386+ raise ValueError ("The payload already exists." )
387+ payload = detached_payload
388+ if payload is None :
389+ raise ValueError ("detached_payload should be set." )
390+
379391 # protected: Union[Dict[int, Any], bytes] = self._loads(data.value[0]) if data.value[0] else b""
380392 # unprotected = data.value[1]
381393 # if not isinstance(unprotected, dict):
@@ -396,18 +408,18 @@ def decode_with_headers(
396408 continue
397409 try :
398410 if not isinstance (p , bytes ) and alg in COSE_ALGORITHMS_HPKE .values (): # HPKE
399- hpke = HPKE (p , u , data . value [ 2 ] )
411+ hpke = HPKE (p , u , payload )
400412 res = hpke .decode (k , aad )
401413 if not isinstance (res , bytes ):
402414 raise TypeError ("Internal type error." )
403415 return p , u , res
404- return p , u , k .decrypt (data . value [ 2 ] , nonce , aad )
416+ return p , u , k .decrypt (payload , nonce , aad )
405417 except Exception as e :
406418 err = e
407419 raise err
408420 for _ , k in enumerate (keys ):
409421 try :
410- return p , u , k .decrypt (data . value [ 2 ] , nonce , aad )
422+ return p , u , k .decrypt (payload , nonce , aad )
411423 except Exception as e :
412424 err = e
413425 raise err
@@ -418,42 +430,42 @@ def decode_with_headers(
418430 nonce = u .get (5 , b"" )
419431 enc_key = rs .derive_key (keys , alg , external_aad , "Enc_Recipient" )
420432 aad = self ._dumps (["Encrypt" , data .value [0 ], external_aad ])
421- return p , u , enc_key .decrypt (data . value [ 2 ] , nonce , aad )
433+ return p , u , enc_key .decrypt (payload , nonce , aad )
422434
423435 # MAC0
424436 if data .tag == 17 :
425437 kid = self ._get_kid (p , u )
426- msg = self ._dumps (["MAC0" , data .value [0 ], external_aad , data . value [ 2 ] ])
438+ msg = self ._dumps (["MAC0" , data .value [0 ], external_aad , payload ])
427439 if kid :
428440 for _ , k in enumerate (keys ):
429441 if k .kid != kid :
430442 continue
431443 try :
432444 k .verify (msg , data .value [3 ])
433- return p , u , data . value [ 2 ]
445+ return p , u , payload
434446 except Exception as e :
435447 err = e
436448 raise err
437449 for _ , k in enumerate (keys ):
438450 try :
439451 k .verify (msg , data .value [3 ])
440- return p , u , data . value [ 2 ]
452+ return p , u , payload
441453 except Exception as e :
442454 err = e
443455 raise err
444456
445457 # MAC
446458 if data .tag == 97 :
447- to_be_maced = self ._dumps (["MAC" , data .value [0 ], external_aad , data . value [ 2 ] ])
459+ to_be_maced = self ._dumps (["MAC" , data .value [0 ], external_aad , payload ])
448460 rs = Recipients .from_list (data .value [4 ], self ._verify_kid , context )
449461 mac_auth_key = rs .derive_key (keys , alg , external_aad , "Mac_Recipient" )
450462 mac_auth_key .verify (to_be_maced , data .value [3 ])
451- return p , u , data . value [ 2 ]
463+ return p , u , payload
452464
453465 # Signature1
454466 if data .tag == 18 :
455467 kid = self ._get_kid (p , u )
456- to_be_signed = self ._dumps (["Signature1" , data .value [0 ], external_aad , data . value [ 2 ] ])
468+ to_be_signed = self ._dumps (["Signature1" , data .value [0 ], external_aad , payload ])
457469 if kid :
458470 for _ , k in enumerate (keys ):
459471 if k .kid != kid :
@@ -462,7 +474,7 @@ def decode_with_headers(
462474 if self ._ca_certs :
463475 k .validate_certificate (self ._ca_certs )
464476 k .verify (to_be_signed , data .value [3 ])
465- return p , u , data . value [ 2 ]
477+ return p , u , payload
466478 except Exception as e :
467479 err = e
468480 raise err
@@ -471,7 +483,7 @@ def decode_with_headers(
471483 if self ._ca_certs :
472484 k .validate_certificate (self ._ca_certs )
473485 k .verify (to_be_signed , data .value [3 ])
474- return p , u , data . value [ 2 ]
486+ return p , u , payload
475487 except Exception as e :
476488 err = e
477489 raise err
@@ -501,11 +513,11 @@ def decode_with_headers(
501513 data .value [0 ],
502514 sig [0 ],
503515 external_aad ,
504- data . value [ 2 ] ,
516+ payload ,
505517 ]
506518 )
507519 k .verify (to_be_signed , sig [2 ])
508- return p , u , data . value [ 2 ]
520+ return p , u , payload
509521 except Exception as e :
510522 err = e
511523 continue
@@ -517,11 +529,11 @@ def decode_with_headers(
517529 data .value [0 ],
518530 sig [0 ],
519531 external_aad ,
520- data . value [ 2 ] ,
532+ payload ,
521533 ]
522534 )
523535 k .verify (to_be_signed , sig [2 ])
524- return p , u , data . value [ 2 ]
536+ return p , u , payload
525537 except Exception as e :
526538 err = e
527539 raise err
0 commit comments