# `SignCore.XML.XAdES`
[🔗](https://github.com/utaladriz/pkcs11ex/blob/v0.1.0/lib/sign_core/xml/xades.ex#L1)

Builds the XAdES B-B `<xades:QualifyingProperties>` block.

Produces the canonical shape ETSI EN 319 132-1 prescribes for B-B:

    <xades:QualifyingProperties Target="#Signature-{id}"
        xmlns:xades="http://uri.etsi.org/01903/v1.3.2#"
        xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
      <xades:SignedProperties Id="xades-{id}">
        <xades:SignedSignatureProperties>
          <xades:SigningTime>2026-05-06T14:05:30Z</xades:SigningTime>
          <xades:SigningCertificateV2>
            <xades:Cert>
              <xades:CertDigest>
                <ds:DigestMethod Algorithm=".../sha256"/>
                <ds:DigestValue>...</ds:DigestValue>
              </xades:CertDigest>
              <xades:IssuerSerialV2>...</xades:IssuerSerialV2>
            </xades:Cert>
          </xades:SigningCertificateV2>
        </xades:SignedSignatureProperties>
      </xades:SignedProperties>
    </xades:QualifyingProperties>

The `<xades:SignedProperties>` element is what the second
`<ds:Reference>` in the signature points at. The verifier
recomputes its exc-c14n digest and matches it against the
reference's `<ds:DigestValue>` — that's how the signature binds
the claimed signing certificate, signing time, and any other
signed properties to the rest of the signed data.

## v1 scope

  * `SigningCertificateV2` with `IssuerSerialV2` (XAdES EN 319
    132-1). The older `SigningCertificate` / `IssuerSerial`
    (TS 101 903 v1.3.2) form is post-v1.
  * Only the leaf cert is digested into `SigningCertificateV2`.
    Including intermediates is allowed by spec but not required
    for B-B; each cert in the chain would otherwise become its
    own `<xades:Cert>` element.
  * `SigningTime` is the only signed-signature-property emitted
    besides `SigningCertificateV2`. `SignaturePolicyIdentifier`,
    `SignatureProductionPlaceV2`, and `SignerRoleV2` are post-v1.

# `build_issuer_serial_v2_der`

```elixir
@spec build_issuer_serial_v2_der(SignCore.X509.t()) ::
  {:ok, binary()} | {:error, term()}
```

Builds the DER-encoded `IssuerSerial` (RFC 5035 §4) octets for a
`<xades:IssuerSerialV2>` element. Returns the raw DER — the caller
base64-encodes it for the XML element body.

## ASN.1 shape

    IssuerSerial ::= SEQUENCE {
        issuer       GeneralNames,
        serialNumber CertificateSerialNumber
    }
    GeneralNames  ::= SEQUENCE OF GeneralName
    GeneralName   ::= CHOICE { ..., directoryName [4] Name, ... }

Single-element `GeneralNames` containing a single `[4] EXPLICIT
Name` is the canonical encoding for an X.509 issuer.

# `qualifying_properties`

```elixir
@spec qualifying_properties(keyword()) :: {:ok, String.t()} | {:error, term()}
```

Builds the full `<xades:QualifyingProperties>` block ready for
splicing into the `<ds:Object>` element of a `<ds:Signature>`.

Required:

  * `:signature_id` — the `Id` of the parent `<ds:Signature>`.
    Used as the `Target` attribute (``).
  * `:signed_properties_id` — the `Id` for `<xades:SignedProperties>`.
    The data Reference's URI in the `<ds:SignedInfo>` block must
    point at `#`.
  * `:leaf_cert` — `SignCore.X509.t()` for the signing cert.

Optional:

  * `:signing_time` — `DateTime.t()`. Default `DateTime.utc_now/0`.

# `splice_unsigned_properties`

```elixir
@spec splice_unsigned_properties(String.t(), String.t()) ::
  {:ok, String.t()} | {:error, term()}
```

Splices an `<xades:UnsignedProperties>` block into the
`<xades:QualifyingProperties>` produced by `qualifying_properties/1`.
Inserts immediately before the `</xades:QualifyingProperties>`
closing tag.

# `unsigned_signature_timestamp`

```elixir
@spec unsigned_signature_timestamp(keyword()) :: {:ok, String.t()} | {:error, term()}
```

Builds the `<xades:UnsignedProperties>` block carrying a
`<xades:SignatureTimeStamp>` (XAdES B-T per ETSI EN 319 132-1
§5.4.1). The TST is embedded base64-encoded as
`<xades:EncapsulatedTimeStamp>`.

    <xades:UnsignedProperties>
      <xades:UnsignedSignatureProperties>
        <xades:SignatureTimeStamp Id="...">
          <ds:CanonicalizationMethod Algorithm="...exc-c14n#"/>
          <xades:EncapsulatedTimeStamp>...</xades:EncapsulatedTimeStamp>
        </xades:SignatureTimeStamp>
      </xades:UnsignedSignatureProperties>
    </xades:UnsignedProperties>

Note: this returns just the `<xades:UnsignedProperties>` block.
Splice it inside the parent `<xades:QualifyingProperties>` after
`<xades:SignedProperties>`.

Required opts:

  * `:tst_der` — RFC 3161 TimeStampToken DER (the
    `Pkcs11ex.Audit.Anchor.RFC3161.extract_token/1` output).
  * `:timestamp_id` — `Id` attribute on the
    `<xades:SignatureTimeStamp>` element.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
