@@ -5,8 +5,10 @@ use libparsec_protocol::anonymous_cmds::latest::pki_enrollment_submit::{Rep, Req
55use libparsec_types:: prelude:: * ;
66use std:: sync:: Arc ;
77
8+ use crate :: ClientConfig ;
9+
810#[ derive( Debug , thiserror:: Error ) ]
9- pub enum ClientPkiEnrollmentSubmitError {
11+ pub enum PkiEnrollmentSubmitError {
1012 #[ error( "Cannot communicate with the server: {0}" ) ]
1113 Offline ( #[ from] ConnectionError ) ,
1214 #[ error( transparent) ]
@@ -21,37 +23,91 @@ pub enum ClientPkiEnrollmentSubmitError {
2123 IdAlreadyUsed ,
2224 #[ error( "Unable to read payload" ) ]
2325 InvalidPayload ,
26+ #[ error( "PKI operation error: {0}" ) ]
27+ PkiOperationError ( anyhow:: Error ) ,
2428}
2529
2630pub async fn pki_enrollment_submit (
27- cmds : & Arc < AnonymousCmds > ,
28- der_x509_certificate : Bytes ,
29- enrollment_id : EnrollmentID ,
31+ config : Arc < ClientConfig > ,
32+ addr : ParsecPkiEnrollmentAddr ,
33+ x509_cert_ref : X509CertificateReference ,
34+ human_handle : HumanHandle ,
35+ device_label : DeviceLabel ,
3036 force : bool ,
31- payload : Bytes ,
32- payload_signature : Bytes ,
33- ) -> Result < DateTime , ClientPkiEnrollmentSubmitError > {
34- let _ = match cmds
37+ ) -> Result < DateTime , PkiEnrollmentSubmitError > {
38+ let cmds = AnonymousCmds :: new (
39+ & config. config_dir ,
40+ ParsecAnonymousAddr :: ParsecPkiEnrollmentAddr ( addr. clone ( ) ) ,
41+ config. proxy . clone ( ) ,
42+ ) ?;
43+
44+ let enrollment_id = EnrollmentID :: default ( ) ;
45+ let signing_key = SigningKey :: generate ( ) ;
46+ let private_key = PrivateKey :: generate ( ) ;
47+
48+ let der_x509_certificate = libparsec_platform_pki:: get_der_encoded_certificate ( & x509_cert_ref)
49+ . map_err ( anyhow:: Error :: from)
50+ . context ( "Failed to get certificate DER content" )
51+ . map_err ( PkiEnrollmentSubmitError :: PkiOperationError ) ?;
52+ let payload = PkiEnrollmentSubmitPayload {
53+ verify_key : signing_key. verify_key ( ) ,
54+ public_key : private_key. public_key ( ) ,
55+ device_label,
56+ human_handle,
57+ } ;
58+ let raw_payload = payload. dump ( ) ;
59+ let payload_signature = libparsec_platform_pki:: sign_message ( & raw_payload, & x509_cert_ref)
60+ . map_err ( anyhow:: Error :: from)
61+ . context ( "Failed to sign payload with PKI" )
62+ . map_err ( PkiEnrollmentSubmitError :: PkiOperationError ) ?;
63+
64+ let submitted_on = match cmds
3565 . send ( Req {
36- der_x509_certificate,
66+ der_x509_certificate : der_x509_certificate . der_content ,
3767 enrollment_id,
3868 force,
39- payload,
40- payload_signature,
69+ payload : raw_payload . into ( ) ,
70+ payload_signature : payload_signature . signature ,
4171 } )
4272 . await ?
4373 {
4474 Rep :: Ok { submitted_on } => Ok ( submitted_on) ,
45- Rep :: AlreadyEnrolled => Err ( ClientPkiEnrollmentSubmitError :: AlreadyEnrolled ) ,
46- Rep :: AlreadySubmitted { submitted_on } => Err (
47- ClientPkiEnrollmentSubmitError :: AlreadySubmitted ( submitted_on) ,
48- ) ,
49- Rep :: EmailAlreadyUsed => Err ( ClientPkiEnrollmentSubmitError :: EmailAlreadyUsed ) ,
50- Rep :: IdAlreadyUsed => Err ( ClientPkiEnrollmentSubmitError :: IdAlreadyUsed ) ,
51- Rep :: InvalidPayload => Err ( ClientPkiEnrollmentSubmitError :: InvalidPayload ) ,
75+ Rep :: AlreadyEnrolled => Err ( PkiEnrollmentSubmitError :: AlreadyEnrolled ) ,
76+ Rep :: AlreadySubmitted { submitted_on } => {
77+ Err ( PkiEnrollmentSubmitError :: AlreadySubmitted ( submitted_on) )
78+ }
79+ Rep :: EmailAlreadyUsed => Err ( PkiEnrollmentSubmitError :: EmailAlreadyUsed ) ,
80+ Rep :: IdAlreadyUsed => Err ( PkiEnrollmentSubmitError :: IdAlreadyUsed ) ,
81+ Rep :: InvalidPayload => Err ( PkiEnrollmentSubmitError :: InvalidPayload ) ,
5282 bad_rep @ Rep :: UnknownStatus { .. } => {
5383 Err ( anyhow:: anyhow!( "Unexpected server response: {:?}" , bad_rep) . into ( ) )
5484 }
85+ } ?;
86+
87+ let private_parts = PrivateParts {
88+ private_key,
89+ signing_key,
5590 } ;
56- todo ! ( "#11440" ) ;
91+ let local_pending = libparsec_platform_pki:: create_local_pending (
92+ & x509_cert_ref,
93+ addr,
94+ enrollment_id,
95+ submitted_on,
96+ payload,
97+ private_parts,
98+ )
99+ . map_err ( anyhow:: Error :: from)
100+ . context ( "Failed to encrypt local parts with PKI" )
101+ . map_err ( PkiEnrollmentSubmitError :: PkiOperationError ) ?;
102+
103+ let local_file = libparsec_platform_device_loader:: get_default_local_pending_file (
104+ & config. config_dir ,
105+ enrollment_id,
106+ ) ;
107+ libparsec_platform_device_loader:: save_pki_local_pending ( local_pending, local_file)
108+ . await
109+ . map_err ( Into :: into)
110+ . map_err ( PkiEnrollmentSubmitError :: Internal ) ?;
111+
112+ Ok ( submitted_on)
57113}
0 commit comments