1+ use std:: borrow:: Cow ;
12use std:: ops:: { ControlFlow , Deref } ;
23use std:: sync:: Arc ;
34use std:: time:: { Duration , Instant , SystemTime } ;
@@ -12,7 +13,7 @@ use tokio::time::sleep;
1213use crate :: account:: AccountInner ;
1314use crate :: types:: {
1415 Authorization , AuthorizationState , AuthorizationStatus , AuthorizedIdentifier , Challenge ,
15- ChallengeType , Empty , FinalizeRequest , OrderState , OrderStatus , Problem ,
16+ ChallengeType , DeviceAttestation , Empty , FinalizeRequest , OrderState , OrderStatus , Problem ,
1617} ;
1718use crate :: { Error , Key , crypto, nonce_from_response, retry_after} ;
1819
@@ -453,6 +454,40 @@ impl ChallengeHandle<'_> {
453454 }
454455 }
455456
457+ /// Notify the server that the challenge is ready by sending a device attestation
458+ ///
459+ /// This function is for the ACME challenge device-attest-01. It should not be used
460+ /// with other challenge types.
461+ /// See <https://datatracker.ietf.org/doc/draft-acme-device-attest/> for details.
462+ ///
463+ /// `payload` is the device attestation object as defined in link. Provide the attestation
464+ /// object as a raw blob. Base64 encoding of the attestation object `payload.att_obj`
465+ /// is done by this function.
466+ pub async fn send_device_attestation (
467+ & mut self ,
468+ payload : & DeviceAttestation < ' _ > ,
469+ ) -> Result < ( ) , Error > {
470+ if self . challenge . r#type != ChallengeType :: DeviceAttest01 {
471+ return Err ( Error :: Str ( "challenge type should be device-attest-01" ) ) ;
472+ }
473+
474+ let payload = DeviceAttestation {
475+ att_obj : Cow :: Owned ( BASE64_URL_SAFE_NO_PAD . encode ( & payload. att_obj ) . into ( ) ) ,
476+ } ;
477+
478+ let rsp = self
479+ . account
480+ . post ( Some ( & payload) , self . nonce . take ( ) , & self . challenge . url )
481+ . await ?;
482+
483+ * self . nonce = nonce_from_response ( & rsp) ;
484+ let response = Problem :: check :: < Challenge > ( rsp) . await ?;
485+ match response. error {
486+ Some ( details) => Err ( Error :: Api ( details) ) ,
487+ None => Ok ( ( ) ) ,
488+ }
489+ }
490+
456491 /// Create a [`KeyAuthorization`] for this challenge
457492 ///
458493 /// Combines a challenge's token with the thumbprint of the account's public key to compute
0 commit comments