pub fn add_assertion_to_xml<W: Write>(&self, writer: &mut EventWriter<W>) {
        // start the assertion
        log::debug!("sign_assertion: {}", self.sign_assertion);

        write_event(
            XmlEvent::start_element(("saml", "Assertion"))
                .attr("xmlns:saml", "urn:oasis:names:tc:SAML:2.0:assertion")
                .attr("ID", &self.assertion_id)
                .attr(
                    "IssueInstant",
                    &self
                        .issue_instant
                        .to_rfc3339_opts(SecondsFormat::Secs, true),
                )
                .attr("Version", "2.0") // yeah, not going to support anything but 2.0 here. 😅
                .into(),
            writer,
        );

        // do the issuer inside the assertion
        write_event(XmlEvent::start_element(("saml", "Issuer")).into(), writer);
        write_event(XmlEvent::characters(&self.issuer), writer);
        write_event(XmlEvent::end_element().into(), writer);

        // if the assertion needs to be signed, we need to generate the whole assertion as a string, sign that, then add it to this assertion.
        if self.sign_assertion {
            log::debug!("Signing assertion");
            if self.signing_key.is_none() {
                panic!("You tried to sign an assertion without setting a signing key...");
            }

            // 1. generate the assertion, a big lump of XML
            let unsigned_assertion = self.clone().without_signature();
            let xmldata: Vec<u8> = unsigned_assertion.into();

            // 2. take a hash of that.
            let digest_bytes = self.digest_algorithm.hash(&xmldata).unwrap();

            // 3. base64 encode #2
            let base64_encoded_digest = base64::encode(&digest_bytes);

            // 4. you put #3 into ANOTHER chunk of XML.
            let mut signedinfo_buffer = Vec::new();
            let mut signedinfo_writer = EmitterConfig::new()
                .perform_indent(true)
                .write_document_declaration(false)
                .normalize_empty_elements(true)
                .pad_self_closing(false)
                .create_writer(&mut signedinfo_buffer);

            crate::xml::generate_signedinfo(self, &base64_encoded_digest, &mut signedinfo_writer);
            log::debug!("SignedInfo Element:");
            log::debug!("{}", from_utf8(&signedinfo_buffer).unwrap());

            // 5. you hash #4.
            let hashed_signedinfo = base64::encode(signedinfo_buffer);
            log::debug!("Hashed Signedinfo: {}", hashed_signedinfo);

            // 6. you sign #5
            let key = self.signing_key.as_ref().unwrap();
            let signed_result =
                crate::sign::sign_data(self.signing_algorithm, key, &hashed_signedinfo.as_bytes());
            log::debug!("Signature result: {:?}", &signed_result);

            let base64_encoded_signature = base64::encode(&signed_result);
            log::debug!(
                "Base64 encoded signature result: {:?}",
                &base64_encoded_signature
            );

            // 7. then you put #4 and #6 inside some other xml inside #1.

            crate::xml::add_assertion_signature(
                self,
                base64_encoded_digest,
                base64_encoded_signature,
                writer,
            );
        } else {
            // add an extra newline to the thing before signing, per https://www.di-mgt.com.au/xmldsig2.html
            // the spaces indent the next tag...
            write_event(XmlEvent::characters("\n  \n  "), writer);

            log::warn!("Unsigned assertion was built, this seems bad!");
        }

        // add the subject to the assertion
        add_subject(&self.subject_data, writer);

        self.add_conditions(writer);

        // To do an expiry in an hour, do this
        // let session_expiry = Utc::now().checked_add_signed(Duration::seconds(3600));

        // self.authnstatement.add_to_xmlevent(&mut writer);

        // start the AttributeStatement
        write_event(
            XmlEvent::start_element(("saml", "AttributeStatement")).into(),
            writer,
        );
        for attribute in &self.attributes.to_vec() {
            add_attribute(attribute, writer);
        }

        // end saml:AttributeStatement
        write_event(XmlEvent::end_element().into(), writer);

        // end the assertion
        write_event(XmlEvent::end_element().into(), writer);
    }
/// This adds the data from an Assertion to a given EventWriter.
///
/// If you specify to *sign* the assertion, it's going to:
/// - generate a temporary EventWriter
/// - generate the *unsigned* assertion
/// - add the signature to the assertion
/// - weep quietly
/// - return the full pack
///
/// That's the plan, anyway.
///
/// ``` xml
/// # Assertion Header
/// - AttributeStatement
/// - AuthnStatement
/// - Conditions
/// - Issuer
/// - Signature
/// - Subject
/// # End Assertion
/// ```
///
This adds the data from an Assertion to a given EventWriter.
If you specify to *sign* the assertion, it's going to:
generate a temporary EventWriter
generate the *unsigned* assertion
add the signature to the assertion
weep quietly
return the full pack

That's the plan, anyway.


This adds the data from an Assertion to a given EventWriter . If you specify to * sign * the assertion it ' s going to : generate a temporary EventWriter generate the * unsigned * assertion add the signature to the assertion weep quietly return the full pack That ' s the plan anyway .
pub fn add_assertion_to_xml<W: Write>(&self, writer: &mut EventWriter<W>) {
        // start the assertion
        log::debug!("sign_assertion: {}", self.sign_assertion);
        write_event(
            XmlEvent::start_element(("saml", "Assertion"))
                .attr("xmlns:saml", "urn:oasis:names:tc:SAML:2.0:assertion")
                .attr("ID", &self.assertion_id)
                .attr(
                    "IssueInstant",
                    &self
                        .issue_instant
                        .to_rfc3339_opts(SecondsFormat::Secs, true),
                )
                .attr("Version", "2.0") // yeah, not going to support anything but 2.0 here. 😅
                .into(),
            writer,
        );
        // do the issuer inside the assertion
        write_event(XmlEvent::start_element(("saml", "Issuer")).into(), writer);
        write_event(XmlEvent::characters(&self.issuer), writer);
        write_event(XmlEvent::end_element().into(), writer);
        // if the assertion needs to be signed, we need to generate the whole assertion as a string, sign that, then add it to this assertion.
        if self.sign_assertion {
            log::debug!("Signing assertion");
            if self.signing_key.is_none() {
                panic!("You tried to sign an assertion without setting a signing key...");
            }
            // 1. generate the assertion, a big lump of XML
            let unsigned_assertion = self.clone().without_signature();
            let xmldata: Vec<u8> = unsigned_assertion.into();
            // 2. take a hash of that.
            let digest_bytes = self.digest_algorithm.hash(&xmldata).unwrap();
            // 3. base64 encode #2
            let base64_encoded_digest = base64::encode(&digest_bytes);
            // 4. you put #3 into ANOTHER chunk of XML.
            let mut signedinfo_buffer = Vec::new();
            let mut signedinfo_writer = EmitterConfig::new()
                .perform_indent(true)
                .write_document_declaration(false)
                .normalize_empty_elements(true)
                .pad_self_closing(false)
                .create_writer(&mut signedinfo_buffer);
            crate::xml::generate_signedinfo(self, &base64_encoded_digest, &mut signedinfo_writer);
            log::debug!("SignedInfo Element:");
            log::debug!("{}", from_utf8(&signedinfo_buffer).unwrap());
            // 5. you hash #4.
            let hashed_signedinfo = base64::encode(signedinfo_buffer);
            log::debug!("Hashed Signedinfo: {}", hashed_signedinfo);
            // 6. you sign #5
            let key = self.signing_key.as_ref().unwrap();
            let signed_result =
                crate::sign::sign_data(self.signing_algorithm, key, &hashed_signedinfo.as_bytes());
            log::debug!("Signature result: {:?}", &signed_result);
            let base64_encoded_signature = base64::encode(&signed_result);
            log::debug!(
                "Base64 encoded signature result: {:?}",
                &base64_encoded_signature
            );
            // 7. then you put #4 and #6 inside some other xml inside #1.
            crate::xml::add_assertion_signature(
                self,
                base64_encoded_digest,
                base64_encoded_signature,
                writer,
            );
        } else {
            // add an extra newline to the thing before signing, per https://www.di-mgt.com.au/xmldsig2.html
            // the spaces indent the next tag...
            write_event(XmlEvent::characters("\n  \n  "), writer);
            log::warn!("Unsigned assertion was built, this seems bad!");
        }
        // add the subject to the assertion
        add_subject(&self.subject_data, writer);
        self.add_conditions(writer);
        // To do an expiry in an hour, do this
        // let session_expiry = Utc::now().checked_add_signed(Duration::seconds(3600));
        // self.authnstatement.add_to_xmlevent(&mut writer);
        // start the AttributeStatement
        write_event(
            XmlEvent::start_element(("saml", "AttributeStatement")).into(),
            writer,
        );
        for attribute in &self.attributes.to_vec() {
            add_attribute(attribute, writer);
        }
        // end saml:AttributeStatement
        write_event(XmlEvent::end_element().into(), writer);
        // end the assertion
        write_event(XmlEvent::end_element().into(), writer);
    }
pub fn add_assertion_to_xml < W : Write > ( & self , writer : & mut EventWriter < W > ) { // start the assertion log :: debug ! ( " " self sign_assertion ) ; write_event ( XmlEvent :: start_element ( ( " " , " " ) ) . attr ( " " , " " ) . attr ( " " , & self . assertion_id ) . attr ( " " , & self . issue_instant . to_rfc3339_opts ( SecondsFormat :: Secs , true ) , ) . attr ( " " , " " ) // yeah, not going to support anything but 2.0 here. 😅 . into ( ) , writer , ) ; // do the issuer inside the assertion write_event ( XmlEvent :: start_element ( ( " " , " " ) ) . into ( ) , writer ) ; write_event ( XmlEvent :: characters ( & self . issuer ) , writer ) ; write_event ( XmlEvent :: end_element ( ) . into ( ) , writer ) ; // if the assertion needs to be signed, we need to generate the whole assertion as a string, sign that, then add it to this assertion. if self . sign_assertion { log :: debug ! ( " " ) ; if self . signing_key . is_none ( ) { panic ! ( " " ) ; } // 1. generate the assertion, a big lump of XML let unsigned_assertion = self . clone ( ) . without_signature ( ) ; let xmldata : Vec < u8 > = unsigned_assertion . into ( ) ; // 2. take a hash of that. let digest_bytes = self . digest_algorithm . hash ( & xmldata ) . unwrap ( ) ; // 3. base64 encode #2 let base64_encoded_digest = base64 :: encode ( & digest_bytes ) ; // 4. you put #3 into ANOTHER chunk of XML. let mut signedinfo_buffer = Vec :: new ( ) ; let mut signedinfo_writer = EmitterConfig :: new ( ) . perform_indent ( true ) . write_document_declaration ( false ) . normalize_empty_elements ( true ) . pad_self_closing ( false ) . create_writer ( & mut signedinfo_buffer ) ; crate :: xml :: generate_signedinfo ( self , & base64_encoded_digest , & mut signedinfo_writer ) ; log :: debug ! ( " " ) ; log :: debug ! ( " " from_utf8 ( signedinfo_buffer ) unwrap ( ) ) ; // 5. you hash #4. let hashed_signedinfo = base64 :: encode ( signedinfo_buffer ) ; log :: debug ! ( " " hashed_signedinfo ) ; // 6. you sign #5 let key = self . signing_key . as_ref ( ) . unwrap ( ) ; let signed_result = crate :: sign :: sign_data ( self . signing_algorithm , key , & hashed_signedinfo . as_bytes ( ) ) ; log :: debug ! ( " " signed_result ) ; let base64_encoded_signature = base64 :: encode ( & signed_result ) ; log :: debug ! ( " " base64_encoded_signature ) ; // 7. then you put #4 and #6 inside some other xml inside #1. crate :: xml :: add_assertion_signature ( self , base64_encoded_digest , base64_encoded_signature , writer , ) ; } else { // add an extra newline to the thing before signing, per https://www.di-mgt.com.au/xmldsig2.html // the spaces indent the next tag... write_event ( XmlEvent :: characters ( " \n \n " ) , writer ) ; log :: warn ! ( " " ) ; } // add the subject to the assertion add_subject ( & self . subject_data , writer ) ; self . add_conditions ( writer ) ; // To do an expiry in an hour, do this // let session_expiry = Utc::now().checked_add_signed(Duration::seconds(3600)); // self.authnstatement.add_to_xmlevent(&mut writer); // start the AttributeStatement write_event ( XmlEvent :: start_element ( ( " " , " " ) ) . into ( ) , writer , ) ; for attribute in & self . attributes . to_vec ( ) { add_attribute ( attribute , writer ) ; } // end saml:AttributeStatement write_event ( XmlEvent :: end_element ( ) . into ( ) , writer ) ; // end the assertion write_event ( XmlEvent :: end_element ( ) . into ( ) , writer ) ; }
This adds the data from an Assertion to a given EventWriter.
This adds the data from an Assertion to a given EventWriter .
&self
writer
&mut EventWriter<W>
&self
writer
&mut EventWriter<W>
assertion header
AttributeStatement
AuthnStatement
Conditions
Issuer
Signature
Subject
AttributeStatement AuthnStatement Conditions Issuer Signature Subject
end assertion
None