Da Vinci Clinical Data Exchange (CDex)
2.1.0 - STU 2.1

Publication Build: This will be filled in by the publication tooling

## Signed Document Bundle Example

Page standards status: Informative

This is a Jupyter Notebook which uses openSSL, Python 3.7, and the Python jcs and jose libraries to create a JSON Web Signature (JWS) (see RFC 7515), attach it to a FHIR Bundle and validate it. Its source code be found here

Although self-signed certificates are used for the purpose of these examples, they are not recommended for production systems.

### Sender/Signer Steps

1. Generate RSA256 public and private keys for signing the bundle

DO THIS STEP ONLY ONCE

2. Create a self-signed certificate for authenticating the signer

create the public and private keys and cert using openssl on the command line.

1. pre-configure the self-signed cert with a configuration file

    [req]
    default_bit = 4096
    distinguished_name = req_distinguished_name
    prompt = no
    x509_extensions = v3_ca

    [req_distinguished_name]
    countryName             = US
    stateOrProvinceName     = California
    localityName            = Sausalito
    organizationName        = HealtheData1
    commonName              = Eric Haas, DVM
    emailAddress            = ehaas@healthedata1.org

    [v3_ca]
    basicConstraints = CA:TRUE
    keyUsage=nonRepudiation, digitalSignature, keyEncipherment
    subjectAltName = @alt_names

    [alt_names]
    DNS.1 = www.healthedatainc.com

2. generate the public and private keys and cert

    !openssl genrsa -out private-key.pem 3072
    !openssl rsa -in private-key.pem -pubout -out public-key.pem
    !openssl req -new -x509 -key private-key.pem -outform DER -out cert.der -days 360 -config cert.config

For the purpose of this example display the keys (normally would never share the private key)

    !cat private-key.pem
    !echo
    !cat public-key.pem

    -----BEGIN RSA PRIVATE KEY-----
    MIIG4wIBAAKCAYEA6SnEpKADOrFttfr1k3iFThsddDFmrEMu1R4nes8qlwATPs53
    wZ13p8lNI9RU7z5kXzg6Dg11bj1MA6JoQh4fm3JVvSjNqOet3MUShLwZ2h67I8Oc
    jZsTuWIxEW4bR3UHqpLXcN1WBEUfR6MSztxZLM0dvdh0weMVt8lpVd4E5DEKMz0n
    CSh92xvD6qugGDyewuGASJVEnQTFZd6p3hH4O37sYhX16H3U1Zu6zIohu1/c+Nz3
    4pamnorH5rUcQJUcBDV6x9zrzgz8i9K05xvArGwF2FSDJnXR3uGRfaZYfebI+KTE
    4S7XCV/6PVxy44exJmcoCR1hEKuD8BcGXZm3H4Qpjq/PB/AW1K7v+1es27BtTdQl
    pZ3ZW1c5y/tyDDq/JF2h3Gp6n3JIBVeBK534xSatTiGgJrDI/OcTJI8ly8nCy/7u
    Z9qOgYPd/1EX6rjqEiBjgkduQ2mc6cNpN7O6BPXTMBFl7X14GLYdm5Y8ubRR9Bo6
    TpMdO4+2U+R58Z5bAgMBAAECggGANf/QZPgSB2PULtNCULcW2HH7Lk/KoZaloAHt
    zslv6azAyEj0/0hCz/8U+HlSel4OzOauu1ZunetgUW8pijaDx3KBXN+4UafmYjzZ
    /xe5PQTk/nFtLnZ96O9OweSoOLJn5h8/+gmoxDBmACdKUdJCbNfMTY117Pl0rC3f
    UV2r8FVTMW62Pa69ByO1CgJZf4N6mVO0bBr12w+hz+fzm1S6Er1gbY78dq29vwLk
    Dj7ndQfMm25Bkp6lVA58IXhMZMCjXSbei1aHxYBXAcAJP5bouiAxqnb2rZ5QM1W1
    CpLuJ0HbGGl0y6aWZenV/C5JEDKqqh62KUGPnTeJLgpJpnuK59y7K+0dcFFKji5C
    0d61lTaOKxHz3X11043j9+pJYJ8bEpxwimO+1i6boBNrB++i5cC8UKxK0Zw6o3HW
    Xfko57EJR6oCiWeorgHZTF6wud4WlRkOMrt7EkrhbPQF8lcahCKGCwI63wxcCtE6
    Wf784Dto+kQSQj6+G2V385utiXExAoHBAP95t1kQdTQl3ASwA3wvnU1oRzsj83DS
    Qrg2vhJlhTUwKIsxKYIvL/KQQFsd4/ejr5nGurlAcFsRlA6cR94LXL2DWvvy52uP
    r1UeOPeJ7DiFu2IY8ehtX9wEbt1dLYkgwTmkwASQIJsaNCgMH+1y5jcWdWGmHqf8
    Y4z3/JerrT1FRT/Sgsp34HrzeCAajyRLK/qzDU1ieXYWVMnv+ZGEl5DFMvFRf0dP
    IJHT7uuHdAvXw1tRcvsYtGIdiHyNDGjcpQKBwQDppFL2n50Fx3oWanXIspWS4Whq
    PgBm2wTz5o+LGQIRj0m6qD5q+/mXdxxzj8zY3qlkQj1YGT2Bog9cYL2+PuNqnHeq
    coi6uVf0zruq9XcrCoYs5sT4GT57LdRQK3xtGXURFbrVc/wjn7rU1/XhqThQADGx
    cHvUVc37Pkvirf0/hAkW3KwOBEsXn8IYJ5JydBOm957NvoEAGCcI9tc0FM7xl4I7
    CMzSYl+i/tXy/sec45Y514LXun8Tvm09uj8Qnv8CgcBX7HDwgxyDLQBy0IzygYSW
    rmvNa8sNqh9yPMzfkfbtXjyl4u6RMmJDDehIM5pQkRIPT3jV5tqETSFygdCuF6T8
    SCfZDDkfKJ1EIxmh/+K/dS8PTNx8jJ/wHcp1/up8BjzZ9Nxs9ZlzJ+qJWdrnIqMe
    lGkjiUOFtvQgAPz6ygfeTWfO1klTGzyzs/VEvz9CU2i4aEUMu/ZncLoPobp3nXV4
    SpYEvXKbfR0Ncy4H+18x8Dj4xahXyKHUHqvpibWapU0CgcEAinvgxNd0neFPZwvx
    BmV7rJS4bAiV+mElPV/SgzLue/P/Uoi4fncdyH5MOd7pHz5TDt8INzi2sSiajDm3
    HZVu/FkDwN6kVnDXRn5m0/0shjF1uBWMeDWWSDKw3lf4Jz5omhjUJgLaV08s0U20
    Ku4/N4P18GNoskGtlpalKhXQvp4HOSrRPHmk/Lqvs9t4vSg6IcQxt2eMVL78HB8b
    DX6r7pzMDyu3I5g1cYo0zBPhwwdOmrg3kKC1A8HiRC0phjOHAoHAbayWoC7XWsKx
    1XzirFof87u47oEAcu0VlOJOwCr270J2Q1jyLMRCvgNQYvZz6nTJt0jcXazZrBTQ
    jkwHgb7kFFSTqrE3Uj8Bmm6O+WnoY2+zi4leSe8yz3SRpLL1w9S1p40XQGLJhIX+
    GJr5shr9osadWap/vzl244Do4Od/NMehLl6ibyu1UteRexDp8JjyUBwAAC50kMYP
    OavUzEG9Ymb4t4yNjaso6C7ZNVcbJTJeI1A153p0uH3xJqFefai2
    -----END RSA PRIVATE KEY-----

    -----BEGIN PUBLIC KEY-----
    MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEA6SnEpKADOrFttfr1k3iF
    ThsddDFmrEMu1R4nes8qlwATPs53wZ13p8lNI9RU7z5kXzg6Dg11bj1MA6JoQh4f
    m3JVvSjNqOet3MUShLwZ2h67I8OcjZsTuWIxEW4bR3UHqpLXcN1WBEUfR6MSztxZ
    LM0dvdh0weMVt8lpVd4E5DEKMz0nCSh92xvD6qugGDyewuGASJVEnQTFZd6p3hH4
    O37sYhX16H3U1Zu6zIohu1/c+Nz34pamnorH5rUcQJUcBDV6x9zrzgz8i9K05xvA
    rGwF2FSDJnXR3uGRfaZYfebI+KTE4S7XCV/6PVxy44exJmcoCR1hEKuD8BcGXZm3
    H4Qpjq/PB/AW1K7v+1es27BtTdQlpZ3ZW1c5y/tyDDq/JF2h3Gp6n3JIBVeBK534
    xSatTiGgJrDI/OcTJI8ly8nCy/7uZ9qOgYPd/1EX6rjqEiBjgkduQ2mc6cNpN7O6
    BPXTMBFl7X14GLYdm5Y8ubRR9Bo6TpMdO4+2U+R58Z5bAgMBAAE=
    -----END PUBLIC KEY-----

Show the Certificate in DER Format

    !openssl x509 -in cert.der -inform DER -text

    Certificate:
        Data:
            Version: 3 (0x2)
            Serial Number: 16322561221100825744 (0xe28562f33047ec90)
        Signature Algorithm: sha256WithRSAEncryption
            Issuer: C=US, ST=California, L=Sausalito, O=HealtheData1, CN=Eric Haas, DVM/emailAddress=ehaas@healthedata1.org
            Validity
                Not Before: Oct 27 17:42:04 2021 GMT
                Not After : Oct 22 17:42:04 2022 GMT
            Subject: C=US, ST=California, L=Sausalito, O=HealtheData1, CN=Eric Haas, DVM/emailAddress=ehaas@healthedata1.org
            Subject Public Key Info:
                Public Key Algorithm: rsaEncryption
                    Public-Key: (3072 bit)
                    Modulus:
                        00:e9:29:c4:a4:a0:03:3a:b1:6d:b5:fa:f5:93:78:
                        85:4e:1b:1d:74:31:66:ac:43:2e:d5:1e:27:7a:cf:
                        2a:97:00:13:3e:ce:77:c1:9d:77:a7:c9:4d:23:d4:
                        54:ef:3e:64:5f:38:3a:0e:0d:75:6e:3d:4c:03:a2:
                        68:42:1e:1f:9b:72:55:bd:28:cd:a8:e7:ad:dc:c5:
                        12:84:bc:19:da:1e:bb:23:c3:9c:8d:9b:13:b9:62:
                        31:11:6e:1b:47:75:07:aa:92:d7:70:dd:56:04:45:
                        1f:47:a3:12:ce:dc:59:2c:cd:1d:bd:d8:74:c1:e3:
                        15:b7:c9:69:55:de:04:e4:31:0a:33:3d:27:09:28:
                        7d:db:1b:c3:ea:ab:a0:18:3c:9e:c2:e1:80:48:95:
                        44:9d:04:c5:65:de:a9:de:11:f8:3b:7e:ec:62:15:
                        f5:e8:7d:d4:d5:9b:ba:cc:8a:21:bb:5f:dc:f8:dc:
                        f7:e2:96:a6:9e:8a:c7:e6:b5:1c:40:95:1c:04:35:
                        7a:c7:dc:eb:ce:0c:fc:8b:d2:b4:e7:1b:c0:ac:6c:
                        05:d8:54:83:26:75:d1:de:e1:91:7d:a6:58:7d:e6:
                        c8:f8:a4:c4:e1:2e:d7:09:5f:fa:3d:5c:72:e3:87:
                        b1:26:67:28:09:1d:61:10:ab:83:f0:17:06:5d:99:
                        b7:1f:84:29:8e:af:cf:07:f0:16:d4:ae:ef:fb:57:
                        ac:db:b0:6d:4d:d4:25:a5:9d:d9:5b:57:39:cb:fb:
                        72:0c:3a:bf:24:5d:a1:dc:6a:7a:9f:72:48:05:57:
                        81:2b:9d:f8:c5:26:ad:4e:21:a0:26:b0:c8:fc:e7:
                        13:24:8f:25:cb:c9:c2:cb:fe:ee:67:da:8e:81:83:
                        dd:ff:51:17:ea:b8:ea:12:20:63:82:47:6e:43:69:
                        9c:e9:c3:69:37:b3:ba:04:f5:d3:30:11:65:ed:7d:
                        78:18:b6:1d:9b:96:3c:b9:b4:51:f4:1a:3a:4e:93:
                        1d:3b:8f:b6:53:e4:79:f1:9e:5b
                    Exponent: 65537 (0x10001)
            X509v3 extensions:
                X509v3 Basic Constraints:
                    CA:TRUE
                X509v3 Key Usage:
                    Digital Signature, Non Repudiation, Key Encipherment
                X509v3 Subject Alternative Name:
                    DNS:www.healthedatainc.com
        Signature Algorithm: sha256WithRSAEncryption
             0a:e3:14:36:af:5a:cb:ef:9e:e5:80:bb:40:53:bd:e2:b7:f3:
             c4:64:27:17:71:a4:95:93:40:5e:62:2b:ec:f5:46:76:21:98:
             d8:64:f1:ff:d4:6d:1c:2c:13:2b:39:0b:fb:2b:ca:a2:37:99:
             f5:d5:4a:f3:0a:c6:56:24:64:3b:f8:d4:c9:9f:8a:71:64:68:
             91:48:ec:e7:d9:dc:24:64:4c:49:24:71:b5:e0:90:ba:3b:78:
             85:fd:be:fe:a5:7e:7f:6b:0c:42:d1:2b:c0:f1:37:d2:f6:ea:
             45:85:0d:34:d0:55:11:0a:5a:43:1f:da:70:90:d4:bf:db:fb:
             b2:31:e2:24:3a:97:c1:0f:ab:ce:3f:79:88:70:08:69:e1:07:
             a8:5f:cc:b3:6d:a9:d9:b7:99:ba:ab:c8:40:a7:8c:97:eb:2f:
             56:a1:ed:8a:ec:d6:9c:5e:14:e9:52:26:a6:4a:f8:6c:79:7b:
             7a:05:7d:1f:a9:7a:4f:64:8c:92:3e:aa:0d:4e:5e:f4:d8:34:
             66:52:d3:b6:8b:2c:84:12:e6:a2:91:7b:7b:b1:f2:ad:31:00:
             99:f3:8f:29:07:b4:12:0f:44:da:ea:f3:c6:a0:6e:1b:9e:24:
             e7:41:b6:27:41:62:3e:c4:09:02:11:62:34:6c:12:83:84:b7:
             1f:25:43:1b:bb:9e:29:dd:0b:f7:7c:0a:38:d3:98:1a:f3:0a:
             8b:30:87:07:ea:4a:bc:43:09:a1:9f:32:f6:e8:81:f8:71:57:
             72:9f:51:68:9a:89:f7:b1:e9:65:31:2f:fa:58:82:a7:63:d2:
             5f:37:0a:d2:bd:b9:49:cc:a3:17:a7:4b:a2:e2:b6:48:1d:f4:
             c4:0b:c9:f2:d1:39:f3:8f:a3:a9:0e:82:19:e7:14:f5:78:ef:
             94:08:ee:25:d0:ab:0d:e5:4f:b2:39:27:ec:e3:d7:1b:ef:17:
             65:4e:f3:a8:76:4d:99:75:f5:61:8e:07:e6:b8:04:27:8f:25:
             ad:4a:cf:dc:8f:11
    -----BEGIN CERTIFICATE-----
    MIIE3zCCA0egAwIBAgIJAOKFYvMwR+yQMA0GCSqGSIb3DQEBCwUAMIGNMQswCQYD
    VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJU2F1c2FsaXRv
    MRUwEwYDVQQKDAxIZWFsdGhlRGF0YTExFzAVBgNVBAMMDkVyaWMgSGFhcywgRFZN
    MSUwIwYJKoZIhvcNAQkBFhZlaGFhc0BoZWFsdGhlZGF0YTEub3JnMB4XDTIxMTAy
    NzE3NDIwNFoXDTIyMTAyMjE3NDIwNFowgY0xCzAJBgNVBAYTAlVTMRMwEQYDVQQI
    DApDYWxpZm9ybmlhMRIwEAYDVQQHDAlTYXVzYWxpdG8xFTATBgNVBAoMDEhlYWx0
    aGVEYXRhMTEXMBUGA1UEAwwORXJpYyBIYWFzLCBEVk0xJTAjBgkqhkiG9w0BCQEW
    FmVoYWFzQGhlYWx0aGVkYXRhMS5vcmcwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAw
    ggGKAoIBgQDpKcSkoAM6sW21+vWTeIVOGx10MWasQy7VHid6zyqXABM+znfBnXen
    yU0j1FTvPmRfODoODXVuPUwDomhCHh+bclW9KM2o563cxRKEvBnaHrsjw5yNmxO5
    YjERbhtHdQeqktdw3VYERR9HoxLO3FkszR292HTB4xW3yWlV3gTkMQozPScJKH3b
    G8Pqq6AYPJ7C4YBIlUSdBMVl3qneEfg7fuxiFfXofdTVm7rMiiG7X9z43Pfilqae
    isfmtRxAlRwENXrH3OvODPyL0rTnG8CsbAXYVIMmddHe4ZF9plh95sj4pMThLtcJ
    X/o9XHLjh7EmZygJHWEQq4PwFwZdmbcfhCmOr88H8BbUru/7V6zbsG1N1CWlndlb
    VznL+3IMOr8kXaHcanqfckgFV4ErnfjFJq1OIaAmsMj85xMkjyXLycLL/u5n2o6B
    g93/URfquOoSIGOCR25DaZzpw2k3s7oE9dMwEWXtfXgYth2bljy5tFH0GjpOkx07
    j7ZT5HnxnlsCAwEAAaNAMD4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCBeAwIQYD
    VR0RBBowGIIWd3d3LmhlYWx0aGVkYXRhaW5jLmNvbTANBgkqhkiG9w0BAQsFAAOC
    AYEACuMUNq9ay++e5YC7QFO94rfzxGQnF3GklZNAXmIr7PVGdiGY2GTx/9RtHCwT
    KzkL+yvKojeZ9dVK8wrGViRkO/jUyZ+KcWRokUjs59ncJGRMSSRxteCQujt4hf2+
    /qV+f2sMQtErwPE30vbqRYUNNNBVEQpaQx/acJDUv9v7sjHiJDqXwQ+rzj95iHAI
    aeEHqF/Ms22p2beZuqvIQKeMl+svVqHtiuzWnF4U6VImpkr4bHl7egV9H6l6T2SM
    kj6qDU5e9Ng0ZlLTtosshBLmopF7e7HyrTEAmfOPKQe0Eg9E2urzxqBuG54k50G2
    J0FiPsQJAhFiNGwSg4S3HyVDG7ueKd0L93wKONOYGvMKizCHB+pKvEMJoZ8y9uiB
    +HFXcp9RaJqJ97HpZTEv+liCp2PSXzcK0r25ScyjF6dLouK2SB30xAvJ8tE584+j
    qQ6CGecU9XjvlAjuJdCrDeVPsjkn7OPXG+8XZU7zqHZNmXX1YY4H5rgEJ48lrUrP
    3I8R
    -----END CERTIFICATE-----

Show the Certificate in PEM format

    !openssl x509 -in cert.der -inform DER -outform PEM -out cert.pem
    !cat cert.pem

    -----BEGIN CERTIFICATE-----
    MIIE3zCCA0egAwIBAgIJAOKFYvMwR+yQMA0GCSqGSIb3DQEBCwUAMIGNMQswCQYD
    VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJU2F1c2FsaXRv
    MRUwEwYDVQQKDAxIZWFsdGhlRGF0YTExFzAVBgNVBAMMDkVyaWMgSGFhcywgRFZN
    MSUwIwYJKoZIhvcNAQkBFhZlaGFhc0BoZWFsdGhlZGF0YTEub3JnMB4XDTIxMTAy
    NzE3NDIwNFoXDTIyMTAyMjE3NDIwNFowgY0xCzAJBgNVBAYTAlVTMRMwEQYDVQQI
    DApDYWxpZm9ybmlhMRIwEAYDVQQHDAlTYXVzYWxpdG8xFTATBgNVBAoMDEhlYWx0
    aGVEYXRhMTEXMBUGA1UEAwwORXJpYyBIYWFzLCBEVk0xJTAjBgkqhkiG9w0BCQEW
    FmVoYWFzQGhlYWx0aGVkYXRhMS5vcmcwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAw
    ggGKAoIBgQDpKcSkoAM6sW21+vWTeIVOGx10MWasQy7VHid6zyqXABM+znfBnXen
    yU0j1FTvPmRfODoODXVuPUwDomhCHh+bclW9KM2o563cxRKEvBnaHrsjw5yNmxO5
    YjERbhtHdQeqktdw3VYERR9HoxLO3FkszR292HTB4xW3yWlV3gTkMQozPScJKH3b
    G8Pqq6AYPJ7C4YBIlUSdBMVl3qneEfg7fuxiFfXofdTVm7rMiiG7X9z43Pfilqae
    isfmtRxAlRwENXrH3OvODPyL0rTnG8CsbAXYVIMmddHe4ZF9plh95sj4pMThLtcJ
    X/o9XHLjh7EmZygJHWEQq4PwFwZdmbcfhCmOr88H8BbUru/7V6zbsG1N1CWlndlb
    VznL+3IMOr8kXaHcanqfckgFV4ErnfjFJq1OIaAmsMj85xMkjyXLycLL/u5n2o6B
    g93/URfquOoSIGOCR25DaZzpw2k3s7oE9dMwEWXtfXgYth2bljy5tFH0GjpOkx07
    j7ZT5HnxnlsCAwEAAaNAMD4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCBeAwIQYD
    VR0RBBowGIIWd3d3LmhlYWx0aGVkYXRhaW5jLmNvbTANBgkqhkiG9w0BAQsFAAOC
    AYEACuMUNq9ay++e5YC7QFO94rfzxGQnF3GklZNAXmIr7PVGdiGY2GTx/9RtHCwT
    KzkL+yvKojeZ9dVK8wrGViRkO/jUyZ+KcWRokUjs59ncJGRMSSRxteCQujt4hf2+
    /qV+f2sMQtErwPE30vbqRYUNNNBVEQpaQx/acJDUv9v7sjHiJDqXwQ+rzj95iHAI
    aeEHqF/Ms22p2beZuqvIQKeMl+svVqHtiuzWnF4U6VImpkr4bHl7egV9H6l6T2SM
    kj6qDU5e9Ng0ZlLTtosshBLmopF7e7HyrTEAmfOPKQe0Eg9E2urzxqBuG54k50G2
    J0FiPsQJAhFiNGwSg4S3HyVDG7ueKd0L93wKONOYGvMKizCHB+pKvEMJoZ8y9uiB
    +HFXcp9RaJqJ97HpZTEv+liCp2PSXzcK0r25ScyjF6dLouK2SB30xAvJ8tE584+j
    qQ6CGecU9XjvlAjuJdCrDeVPsjkn7OPXG+8XZU7zqHZNmXX1YY4H5rgEJ48lrUrP
    3I8R
    -----END CERTIFICATE-----

3. Create JWS to Attach to Bundle

3.1. Prepare Header

note the base64 DER is Cert PEM file wihout the footer and header and line returns

    with open('cert.pem') as f:
        der = (f.read())  # base64 DER is PEM wihout the footer and header and line returns
    der = der.replace('-----BEGIN CERTIFICATE-----','')
    der = der.replace('-----END CERTIFICATE-----','')
    der = der.replace('\n','')

    header = {"alg": "RS256","kty": "RS", "x5c": [der]}
    header

    {'alg': 'RS256',
     'kty': 'RS',
     'x5c': [' ']}

3.2. Prepare Payload

The payload is the base64_url form of the canonicalized version of the document Bundle before attaching the signature

Canonicalize the bundle using IETF JSON Canonicalization Scheme (JCS) before adding the signature element:

- Remove the id and meta elements if present before canonicalization
- The base64_url of the payload entry is combined with 3.3 below using the jws.sign method.

    from jcs import canonicalize #package for a JCS (RFC 8785) compliant canonicalizer.
    from json import loads
    document_bundle = r'''{
      "resourceType": "Bundle",
      "id": "cdex-document-digital-sig-example",
      "meta": {
        "extension": [
          {
            "url": "http://hl7.org/fhir/StructureDefinition/instance-name",
            "valueString": "CDEX Document with Digital Signature Example"
          },
          {
            "url": "http://hl7.org/fhir/StructureDefinition/instance-description",
            "valueMarkdown": "Digital signature example showing how it is used to sign a FHIR Document.  The CDEX use case would be the target resource in response to a Task-based request where an digital signature was required.  If no signature was required, the response would typically be in the form of an individual resource."
          }
        ]
      },
      "identifier": {
        "system": "urn:ietf:rfc:3986",
        "value": "urn:uuid:c173535e-135e-48e3-ab64-38bacc68dba8"
      },
      "type": "document",
      "timestamp": "2021-10-25T20:16:29-07:00",
      "entry": [
        {
          "fullUrl": "urn:uuid:17a80a8d-4cf1-4deb-a1fd-2db1130e5f76",
          "resource": {
            "resourceType": "Composition",
            "id": "17a80a8d-4cf1-4deb-a1fd-2db1130e5f76",
            "text": {
              "status": "generated",
              "div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"><p><b>Generated Narrative</b></p><div style=\"display: inline-block; background-color: #d9e0e7; padding: 6px; margin: 4px; border: 1px solid #8da1b4; border-radius: 5px; line-height: 60%\"><p style=\"margin-bottom: 0px\">Resource \"17a80a8d-4cf1-4deb-a1fd-2db1130e5f76\" </p></div><p><b>status</b>: final</p><p><b>type</b>: Medical records <span style=\"background: LightGoldenRodYellow; margin: 4px; border: 1px solid khaki\"> (<a href=\"https://loinc.org/\">LOINC</a>#11503-0)</span></p><p><b>encounter</b>: <a href=\"#Encounter_5ce5c83a-000f-47d2-941c-039358cc9112\">See above (urn:uuid:5ce5c83a-000f-47d2-941c-039358cc9112: Example Encounter)</a></p><p><b>date</b>: 2021-10-25T20:16:29-07:00</p><p><b>author</b>: <a href=\"#Practitioner_0820c16d-91de-4dfa-a3a6-f140a516a9bc\">See above (urn:uuid:0820c16d-91de-4dfa-a3a6-f140a516a9bc: Example Practitioner)</a></p><p><b>title</b>: Active Conditions</p><h3>Attesters</h3><table class=\"grid\"><tr><td>-</td><td><b>Mode</b></td><td><b>Time</b></td><td><b>Party</b></td></tr><tr><td>*</td><td>legal</td><td>2021-10-25T20:16:29-07:00</td><td><a href=\"#Practitioner_0820c16d-91de-4dfa-a3a6-f140a516a9bc\">See above (urn:uuid:0820c16d-91de-4dfa-a3a6-f140a516a9bc: Example Practitioner)</a></td></tr></table></div>"
            },
            "status": "final",
            "type": {
              "coding": [
                {
                  "system": "http://loinc.org",
                  "code": "11503-0"
                }
              ],
              "text": "Medical records"
            },
            "subject": {
              "reference": "urn:uuid:970af6c9-5bbd-4067-b6c1-d9b2c823aece",
              "display": "Example Patient"
            },
            "encounter": {
              "reference": "urn:uuid:5ce5c83a-000f-47d2-941c-039358cc9112",
              "display": "Example Encounter"
            },
            "date": "2021-10-25T20:16:29-07:00",
            "author": [
              {
                "reference": "urn:uuid:0820c16d-91de-4dfa-a3a6-f140a516a9bc",
                "display": "Example Practitioner"
              }
            ],
            "title": "Active Conditions",
            "attester": [
              {
                "mode": "legal",
                "time": "2021-10-25T20:16:29-07:00",
                "party": {
                  "reference": "urn:uuid:0820c16d-91de-4dfa-a3a6-f140a516a9bc",
                  "display": "Example Practitioner"
                }
              }
            ],
            "section": [
              {
                "title": "Active Condition 1",
                "entry": [
                  {
                    "reference": "urn:uuid:014a68ec-d691-49e0-b980-91b0d924e570"
                  }
                ]
              }
            ]
          }
        },
        {
          "fullUrl": "urn:uuid:0820c16d-91de-4dfa-a3a6-f140a516a9bc",
          "resource": {
            "resourceType": "Practitioner",
            "id": "0820c16d-91de-4dfa-a3a6-f140a516a9bc",
            "meta": {
              "lastUpdated": "2013-05-05T16:13:03Z"
            },
            "text": {
              "status": "generated",
              "div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"><p><b>Generated Narrative</b></p><div style=\"display: inline-block; background-color: #d9e0e7; padding: 6px; margin: 4px; border: 1px solid #8da1b4; border-radius: 5px; line-height: 60%\"><p style=\"margin-bottom: 0px\">Resource \"0820c16d-91de-4dfa-a3a6-f140a516a9bc\" Updated \"2013-05-05T16:13:03Z\" </p></div><p><b>name</b>: John Hancock </p></div>"
            },
            "name": [
              {
                "family": "Hancock",
                "given": [
                  "John"
                ]
              }
            ]
          }
        },
        {
          "fullUrl": "urn:uuid:970af6c9-5bbd-4067-b6c1-d9b2c823aece",
          "resource": {
            "resourceType": "Patient",
            "id": "970af6c9-5bbd-4067-b6c1-d9b2c823aece",
            "text": {
              "status": "generated",
              "div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"><p><b>Generated Narrative</b></p><div style=\"display: inline-block; background-color: #d9e0e7; padding: 6px; margin: 4px; border: 1px solid #8da1b4; border-radius: 5px; line-height: 60%\"><p style=\"margin-bottom: 0px\">Resource \"970af6c9-5bbd-4067-b6c1-d9b2c823aece\" </p></div><p><b>active</b>: true</p><p><b>name</b>: CDEX Example Patient</p></div>"
            },
            "active": true,
            "name": [
              {
                "text": "CDEX Example Patient",
                "family": "Patient",
                "given": [
                  "CDEX Example"
                ]
              }
            ]
          }
        },
        {
          "fullUrl": "urn:uuid:014a68ec-d691-49e0-b980-91b0d924e570",
          "resource": {
            "resourceType": "Condition",
            "id": "014a68ec-d691-49e0-b980-91b0d924e570",
            "text": {
              "status": "generated",
              "div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"><p><b>Generated Narrative</b></p><div style=\"display: inline-block; background-color: #d9e0e7; padding: 6px; margin: 4px; border: 1px solid #8da1b4; border-radius: 5px; line-height: 60%\"><p style=\"margin-bottom: 0px\">Resource \"014a68ec-d691-49e0-b980-91b0d924e570\" </p></div><p><b>identifier</b>: id: 1</p><p><b>clinicalStatus</b>: Active <span style=\"background: LightGoldenRodYellow; margin: 4px; border: 1px solid khaki\"> (<a href=\"http://terminology.hl7.org/3.0.0/CodeSystem-condition-clinical.html\">Condition Clinical Status Codes</a>#active)</span></p><p><b>category</b>: Problem <span style=\"background: LightGoldenRodYellow; margin: 4px; border: 1px solid khaki\"> (<a href=\"https://browser.ihtsdotools.org/\">SNOMED CT</a>#55607006; <a href=\"https://loinc.org/\">LOINC</a>#75326-9)</span></p><p><b>code</b>: Type 2 Diabetes Mellitus <span style=\"background: LightGoldenRodYellow; margin: 4px; border: 1px solid khaki\"> (<a href=\"https://browser.ihtsdotools.org/\">SNOMED CT</a>#44054006)</span></p><p><b>subject</b>: <a href=\"#Patient_970af6c9-5bbd-4067-b6c1-d9b2c823aece\">See above (urn:uuid:970af6c9-5bbd-4067-b6c1-d9b2c823aece)</a></p><p><b>onset</b>: 2006-01-01</p><p><b>asserter</b>: <a href=\"#Practitioner_0820c16d-91de-4dfa-a3a6-f140a516a9bc\">See above (urn:uuid:0820c16d-91de-4dfa-a3a6-f140a516a9bc)</a></p></div>"
            },
            "identifier": [
              {
                "system": "urn:oid:1.3.6.1.4.1.22812.4.111.0.4.1.2.1",
                "value": "1"
              }
            ],
            "clinicalStatus": {
              "coding": [
                {
                  "system": "http://terminology.hl7.org/CodeSystem/condition-clinical",
                  "code": "active"
                }
              ]
            },
            "category": [
              {
                "coding": [
                  {
                    "system": "http://snomed.info/sct",
                    "code": "55607006",
                    "display": "Problem"
                  },
                  {
                    "system": "http://loinc.org",
                    "code": "75326-9",
                    "display": "Problem"
                  }
                ]
              }
            ],
            "code": {
              "coding": [
                {
                  "system": "http://snomed.info/sct",
                  "code": "44054006",
                  "display": "Type 2 Diabetes Mellitus"
                }
              ]
            },
            "subject": {
              "reference": "urn:uuid:970af6c9-5bbd-4067-b6c1-d9b2c823aece"
            },
            "onsetDateTime": "2006",
            "asserter": {
              "reference": "urn:uuid:0820c16d-91de-4dfa-a3a6-f140a516a9bc"
            }
          }
        },
        {
          "fullUrl": "urn:uuid:5ce5c83a-000f-47d2-941c-039358cc9112",
          "resource": {
            "resourceType": "Encounter",
            "id": "5ce5c83a-000f-47d2-941c-039358cc9112",
            "text": {
              "status": "generated",
              "div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"><p><b>Generated Narrative</b></p><div style=\"display: inline-block; background-color: #d9e0e7; padding: 6px; margin: 4px; border: 1px solid #8da1b4; border-radius: 5px; line-height: 60%\"><p style=\"margin-bottom: 0px\">Resource \"5ce5c83a-000f-47d2-941c-039358cc9112\" </p></div><p><b>status</b>: finished</p><p><b>class</b>: emergency (Details: http://terminology.hl7.org/CodeSystem/v3-ActCode code EMER = 'emergency', stated as 'null')</p><p><b>type</b>: Unknown (qualifier value) <span style=\"background: LightGoldenRodYellow; margin: 4px; border: 1px solid khaki\"> (<a href=\"https://browser.ihtsdotools.org/\">SNOMED CT</a>#261665006)</span></p><p><b>subject</b>: <a href=\"#Patient_970af6c9-5bbd-4067-b6c1-d9b2c823aece\">See above (urn:uuid:970af6c9-5bbd-4067-b6c1-d9b2c823aece: CDEX Example Patient)</a></p><h3>Participants</h3><table class=\"grid\"><tr><td>-</td><td><b>Individual</b></td></tr><tr><td>*</td><td><a href=\"#Practitioner_0820c16d-91de-4dfa-a3a6-f140a516a9bc\">See above (urn:uuid:0820c16d-91de-4dfa-a3a6-f140a516a9bc: John Hancock)</a></td></tr></table><p><b>period</b>: 2021-10-25T20:10:29-07:00 --&gt; 2021-10-25T20:16:29-07:00</p><p><b>serviceProvider</b>: <a href=\"#Organization_e37f004b-dc10-422b-b833-cdaa10a055a3\">See above (urn:uuid:e37f004b-dc10-422b-b833-cdaa10a055a3: CDEX Example Organization)</a></p></div>"
            },
            "status": "finished",
            "class": {
              "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
              "code": "EMER"
            },
            "type": [
              {
                "coding": [
                  {
                    "system": "http://snomed.info/sct",
                    "code": "261665006",
                    "display": "Unknown (qualifier value)"
                  }
                ],
                "text": "Unknown (qualifier value)"
              }
            ],
            "subject": {
              "reference": "urn:uuid:970af6c9-5bbd-4067-b6c1-d9b2c823aece",
              "display": "CDEX Example Patient"
            },
            "participant": [
              {
                "individual": {
                  "reference": "urn:uuid:0820c16d-91de-4dfa-a3a6-f140a516a9bc",
                  "display": "John Hancock"
                }
              }
            ],
            "period": {
              "start": "2021-10-25T20:10:29-07:00",
              "end": "2021-10-25T20:16:29-07:00"
            },
            "serviceProvider": {
              "reference": "urn:uuid:e37f004b-dc10-422b-b833-cdaa10a055a3",
              "display": "CDEX Example Organization"
            }
          }
        },
        {
          "fullUrl": "urn:uuid:e37f004b-dc10-422b-b833-cdaa10a055a3",
          "resource": {
            "resourceType": "Organization",
            "id": "e37f004b-dc10-422b-b833-cdaa10a055a3",
            "text": {
              "status": "generated",
              "div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"><p><b>Generated Narrative</b></p><div style=\"display: inline-block; background-color: #d9e0e7; padding: 6px; margin: 4px; border: 1px solid #8da1b4; border-radius: 5px; line-height: 60%\"><p style=\"margin-bottom: 0px\">Resource \"e37f004b-dc10-422b-b833-cdaa10a055a3\" </p></div><p><b>active</b>: true</p><p><b>name</b>: CDEX Example Organization</p><p><b>telecom</b>: ph: (+1) 555-555-5555, <a href=\"mailto:customer-service@example.org\">customer-service@example.org</a></p><p><b>address</b>: 1 CDEX Lane Boston MA 01002 USA </p></div>"
            },
            "active": true,
            "name": "CDEX Example Organization",
            "telecom": [
              {
                "system": "phone",
                "value": "(+1) 555-555-5555"
              },
              {
                "system": "email",
                "value": "customer-service@example.org"
              }
            ],
            "address": [
              {
                "line": [
                  "1 CDEX Lane"
                ],
                "city": "Boston",
                "state": "MA",
                "postalCode": "01002",
                "country": "USA"
              }
            ]
          }
        }
      ]
    }'''
    document_bundle = loads(document_bundle) #convert to Python object
    document_bundle_id = document_bundle.pop("id") # remove id
    document_bundle_meta = document_bundle.pop("meta") # remove meta
    payload = canonicalize(document_bundle)
    payload

    b'{"entry":[{"fullUrl":"urn:uuid:17a80a8d-4cf1-4deb-a1fd-2db1130e5f76","resource":{"attester":[{"mode":"legal","party":{"display":"Example Practitioner","reference":"urn:uuid:0820c16d-91de-4dfa-a3a6-f140a516a9bc"},"time":"2021-10-25T20:16:29-07:00"}],"author":[{"display":"Example Practitioner","reference":"urn:uuid:0820c16d-91de-4dfa-a3a6-f140a516a9bc"}],"date":"2021-10-25T20:16:29-07:00","encounter":{"display":"Example Encounter","reference":"urn:uuid:5ce5c83a-000f-47d2-941c-039358cc9112"},"id":"17a80a8d-4cf1-4deb-a1fd-2db1130e5f76","resourceType":"Composition","section":[{"entry":[{"reference":"urn:uuid:014a68ec-d691-49e0-b980-91b0d924e570"}],"title":"Active Condition 1"}],"status":"final","subject":{"display":"Example Patient","reference":"urn:uuid:970af6c9-5bbd-4067-b6c1-d9b2c823aece"},"text":{"div":"<div xmlns=\\"http://www.w3.org/1999/xhtml\\"><p><b>Generated Narrative</b></p><div style=\\"display: inline-block; background-color: #d9e0e7; padding: 6px; margin: 4px; border: 1px solid #8da1b4; border-radius: 5px; line-height: 60%\\"><p style=\\"margin-bottom: 0px\\">Resource \\"17a80a8d-4cf1-4deb-a1fd-2db1130e5f76\\" </p></div><p><b>status</b>: final</p><p><b>type</b>: Medical records <span style=\\"background: LightGoldenRodYellow; margin: 4px; border: 1px solid khaki\\"> (<a href=\\"https://loinc.org/\\">LOINC</a>#11503-0)</span></p><p><b>encounter</b>: <a href=\\"#Encounter_5ce5c83a-000f-47d2-941c-039358cc9112\\">See above (urn:uuid:5ce5c83a-000f-47d2-941c-039358cc9112: Example Encounter)</a></p><p><b>date</b>: 2021-10-25T20:16:29-07:00</p><p><b>author</b>: <a href=\\"#Practitioner_0820c16d-91de-4dfa-a3a6-f140a516a9bc\\">See above (urn:uuid:0820c16d-91de-4dfa-a3a6-f140a516a9bc: Example Practitioner)</a></p><p><b>title</b>: Active Conditions</p><h3>Attesters</h3><table class=\\"grid\\"><tr><td>-</td><td><b>Mode</b></td><td><b>Time</b></td><td><b>Party</b></td></tr><tr><td>*</td><td>legal</td><td>2021-10-25T20:16:29-07:00</td><td><a href=\\"#Practitioner_0820c16d-91de-4dfa-a3a6-f140a516a9bc\\">See above (urn:uuid:0820c16d-91de-4dfa-a3a6-f140a516a9bc: Example Practitioner)</a></td></tr></table></div>","status":"generated"},"title":"Active Conditions","type":{"coding":[{"code":"11503-0","system":"http://loinc.org"}],"text":"Medical records"}}},{"fullUrl":"urn:uuid:0820c16d-91de-4dfa-a3a6-f140a516a9bc","resource":{"id":"0820c16d-91de-4dfa-a3a6-f140a516a9bc","meta":{"lastUpdated":"2013-05-05T16:13:03Z"},"name":[{"family":"Hancock","given":["John"]}],"resourceType":"Practitioner","text":{"div":"<div xmlns=\\"http://www.w3.org/1999/xhtml\\"><p><b>Generated Narrative</b></p><div style=\\"display: inline-block; background-color: #d9e0e7; padding: 6px; margin: 4px; border: 1px solid #8da1b4; border-radius: 5px; line-height: 60%\\"><p style=\\"margin-bottom: 0px\\">Resource \\"0820c16d-91de-4dfa-a3a6-f140a516a9bc\\" Updated \\"2013-05-05T16:13:03Z\\" </p></div><p><b>name</b>: John Hancock </p></div>","status":"generated"}}},{"fullUrl":"urn:uuid:970af6c9-5bbd-4067-b6c1-d9b2c823aece","resource":{"active":true,"id":"970af6c9-5bbd-4067-b6c1-d9b2c823aece","name":[{"family":"Patient","given":["CDEX Example"],"text":"CDEX Example Patient"}],"resourceType":"Patient","text":{"div":"<div xmlns=\\"http://www.w3.org/1999/xhtml\\"><p><b>Generated Narrative</b></p><div style=\\"display: inline-block; background-color: #d9e0e7; padding: 6px; margin: 4px; border: 1px solid #8da1b4; border-radius: 5px; line-height: 60%\\"><p style=\\"margin-bottom: 0px\\">Resource \\"970af6c9-5bbd-4067-b6c1-d9b2c823aece\\" </p></div><p><b>active</b>: true</p><p><b>name</b>: CDEX Example Patient</p></div>","status":"generated"}}},{"fullUrl":"urn:uuid:014a68ec-d691-49e0-b980-91b0d924e570","resource":{"asserter":{"reference":"urn:uuid:0820c16d-91de-4dfa-a3a6-f140a516a9bc"},"category":[{"coding":[{"code":"55607006","display":"Problem","system":"http://snomed.info/sct"},{"code":"75326-9","display":"Problem","system":"http://loinc.org"}]}],"clinicalStatus":{"coding":[{"code":"active","system":"http://terminology.hl7.org/CodeSystem/condition-clinical"}]},"code":{"coding":[{"code":"44054006","display":"Type 2 Diabetes Mellitus","system":"http://snomed.info/sct"}]},"id":"014a68ec-d691-49e0-b980-91b0d924e570","identifier":[{"system":"urn:oid:1.3.6.1.4.1.22812.4.111.0.4.1.2.1","value":"1"}],"onsetDateTime":"2006","resourceType":"Condition","subject":{"reference":"urn:uuid:970af6c9-5bbd-4067-b6c1-d9b2c823aece"},"text":{"div":"<div xmlns=\\"http://www.w3.org/1999/xhtml\\"><p><b>Generated Narrative</b></p><div style=\\"display: inline-block; background-color: #d9e0e7; padding: 6px; margin: 4px; border: 1px solid #8da1b4; border-radius: 5px; line-height: 60%\\"><p style=\\"margin-bottom: 0px\\">Resource \\"014a68ec-d691-49e0-b980-91b0d924e570\\" </p></div><p><b>identifier</b>: id: 1</p><p><b>clinicalStatus</b>: Active <span style=\\"background: LightGoldenRodYellow; margin: 4px; border: 1px solid khaki\\"> (<a href=\\"http://terminology.hl7.org/3.0.0/CodeSystem-condition-clinical.html\\">Condition Clinical Status Codes</a>#active)</span></p><p><b>category</b>: Problem <span style=\\"background: LightGoldenRodYellow; margin: 4px; border: 1px solid khaki\\"> (<a href=\\"https://browser.ihtsdotools.org/\\">SNOMED CT</a>#55607006; <a href=\\"https://loinc.org/\\">LOINC</a>#75326-9)</span></p><p><b>code</b>: Type 2 Diabetes Mellitus <span style=\\"background: LightGoldenRodYellow; margin: 4px; border: 1px solid khaki\\"> (<a href=\\"https://browser.ihtsdotools.org/\\">SNOMED CT</a>#44054006)</span></p><p><b>subject</b>: <a href=\\"#Patient_970af6c9-5bbd-4067-b6c1-d9b2c823aece\\">See above (urn:uuid:970af6c9-5bbd-4067-b6c1-d9b2c823aece)</a></p><p><b>onset</b>: 2006-01-01</p><p><b>asserter</b>: <a href=\\"#Practitioner_0820c16d-91de-4dfa-a3a6-f140a516a9bc\\">See above (urn:uuid:0820c16d-91de-4dfa-a3a6-f140a516a9bc)</a></p></div>","status":"generated"}}},{"fullUrl":"urn:uuid:5ce5c83a-000f-47d2-941c-039358cc9112","resource":{"class":{"code":"EMER","system":"http://terminology.hl7.org/CodeSystem/v3-ActCode"},"id":"5ce5c83a-000f-47d2-941c-039358cc9112","participant":[{"individual":{"display":"John Hancock","reference":"urn:uuid:0820c16d-91de-4dfa-a3a6-f140a516a9bc"}}],"period":{"end":"2021-10-25T20:16:29-07:00","start":"2021-10-25T20:10:29-07:00"},"resourceType":"Encounter","serviceProvider":{"display":"CDEX Example Organization","reference":"urn:uuid:e37f004b-dc10-422b-b833-cdaa10a055a3"},"status":"finished","subject":{"display":"CDEX Example Patient","reference":"urn:uuid:970af6c9-5bbd-4067-b6c1-d9b2c823aece"},"text":{"div":"<div xmlns=\\"http://www.w3.org/1999/xhtml\\"><p><b>Generated Narrative</b></p><div style=\\"display: inline-block; background-color: #d9e0e7; padding: 6px; margin: 4px; border: 1px solid #8da1b4; border-radius: 5px; line-height: 60%\\"><p style=\\"margin-bottom: 0px\\">Resource \\"5ce5c83a-000f-47d2-941c-039358cc9112\\" </p></div><p><b>status</b>: finished</p><p><b>class</b>: emergency (Details: http://terminology.hl7.org/CodeSystem/v3-ActCode code EMER = \'emergency\', stated as \'null\')</p><p><b>type</b>: Unknown (qualifier value) <span style=\\"background: LightGoldenRodYellow; margin: 4px; border: 1px solid khaki\\"> (<a href=\\"https://browser.ihtsdotools.org/\\">SNOMED CT</a>#261665006)</span></p><p><b>subject</b>: <a href=\\"#Patient_970af6c9-5bbd-4067-b6c1-d9b2c823aece\\">See above (urn:uuid:970af6c9-5bbd-4067-b6c1-d9b2c823aece: CDEX Example Patient)</a></p><h3>Participants</h3><table class=\\"grid\\"><tr><td>-</td><td><b>Individual</b></td></tr><tr><td>*</td><td><a href=\\"#Practitioner_0820c16d-91de-4dfa-a3a6-f140a516a9bc\\">See above (urn:uuid:0820c16d-91de-4dfa-a3a6-f140a516a9bc: John Hancock)</a></td></tr></table><p><b>period</b>: 2021-10-25T20:10:29-07:00 --> 2021-10-25T20:16:29-07:00</p><p><b>serviceProvider</b>: <a href=\\"#Organization_e37f004b-dc10-422b-b833-cdaa10a055a3\\">See above (urn:uuid:e37f004b-dc10-422b-b833-cdaa10a055a3: CDEX Example Organization)</a></p></div>","status":"generated"},"type":[{"coding":[{"code":"261665006","display":"Unknown (qualifier value)","system":"http://snomed.info/sct"}],"text":"Unknown (qualifier value)"}]}},{"fullUrl":"urn:uuid:e37f004b-dc10-422b-b833-cdaa10a055a3","resource":{"active":true,"address":[{"city":"Boston","country":"USA","line":["1 CDEX Lane"],"postalCode":"01002","state":"MA"}],"id":"e37f004b-dc10-422b-b833-cdaa10a055a3","name":"CDEX Example Organization","resourceType":"Organization","telecom":[{"system":"phone","value":"(+1) 555-555-5555"},{"system":"email","value":"customer-service@example.org"}],"text":{"div":"<div xmlns=\\"http://www.w3.org/1999/xhtml\\"><p><b>Generated Narrative</b></p><div style=\\"display: inline-block; background-color: #d9e0e7; padding: 6px; margin: 4px; border: 1px solid #8da1b4; border-radius: 5px; line-height: 60%\\"><p style=\\"margin-bottom: 0px\\">Resource \\"e37f004b-dc10-422b-b833-cdaa10a055a3\\" </p></div><p><b>active</b>: true</p><p><b>name</b>: CDEX Example Organization</p><p><b>telecom</b>: ph: (+1) 555-555-5555, <a href=\\"mailto:customer-service@example.org\\">customer-service@example.org</a></p><p><b>address</b>: 1 CDEX Lane Boston MA 01002 USA </p></div>","status":"generated"}}}],"identifier":{"system":"urn:ietf:rfc:3986","value":"urn:uuid:c173535e-135e-48e3-ab64-38bacc68dba8"},"resourceType":"Bundle","timestamp":"2021-10-25T20:16:29-07:00","type":"document"}'

3.3 Create Signature using private key and the RS256 algorithm to get the JWS compact serialization format

note the signature is displayed with the parts labeled and separated with line breaks for easier viewing.

    from jose import jws
    with open('private-key.pem') as f:
        private_key = (f.read())

    signature = jws.sign(payload,private_key,algorithm='RS256',headers=header)

    labels = ['header', 'payload', 'signature']
    for i,j in enumerate(signature.split('.')):
        print(f'{labels[i]}:')
        print(f'{j}')
        print()

    header:

    payload:

    signature:

3.4. Create detached payload by removing the payload from the JWS

note the signature is displayed with the parts labeled and separated with line breaks for easier viewing then as compact serialization format

    split_sig = signature.split('.')
    split_sig[1] = ''
    signature = '.'.join(split_sig)
    for i,j in enumerate(signature.split('.')):
        print(f'{labels[i]}:')
        print(f'{j}')
        print()
    print(f'\nSignature in compact serialization format:\n{"="*80}\n{signature}')

    header:

    payload:

    signature:

    Signature in compact serialization format:
    ================================================================================
     ..

4. base64 the JWS and add the Signature element to the Bundle

this is what would be contained and/or referenced by TASK over-the-wire

    from base64 import b64encode
    from json import loads,dumps
    b64_jws = b64encode(signature.encode()).decode()
    sig_element = {
                "type": [  # Signature.type = Verification Signature
                  {
                    "system": "urn:iso-astm:E1762-95:2013",
                    "code": "1.2.840.10065.1.12.1.5",
                    "display": "Verification Signature"
                  }
                ],
                "when": "2021-10-05T22:42:19-07:00", #system timestamp when signature created
                "who": { #Reference to the Practitioner who signed and attested to the Bundle
                  "reference": "Practitioner/123"
                },
                "onBehalfOf": { #Reference to the Organization
                  "reference": "Organization/123"
                },
                "data": b64_jws,
                 }

    document_bundle = loads(payload)
    document_bundle['id'] = document_bundle_id # add id back in
    document_bundle['meta'] = document_bundle_meta # add meta back in
    document_bundle['signature'] = sig_element
    print(dumps(document_bundle, indent=2))

    {
      "entry": [
        {
          "fullUrl": "urn:uuid:17a80a8d-4cf1-4deb-a1fd-2db1130e5f76",
          "resource": {
            "attester": [
              {
                "mode": "legal",
                "party": {
                  "display": "Example Practitioner",
                  "reference": "urn:uuid:0820c16d-91de-4dfa-a3a6-f140a516a9bc"
                },
                "time": "2021-10-25T20:16:29-07:00"
              }
            ],
            "author": [
              {
                "display": "Example Practitioner",
                "reference": "urn:uuid:0820c16d-91de-4dfa-a3a6-f140a516a9bc"
              }
            ],
            "date": "2021-10-25T20:16:29-07:00",
            "encounter": {
              "display": "Example Encounter",
              "reference": "urn:uuid:5ce5c83a-000f-47d2-941c-039358cc9112"
            },
            "id": "17a80a8d-4cf1-4deb-a1fd-2db1130e5f76",
            "resourceType": "Composition",
            "section": [
              {
                "entry": [
                  {
                    "reference": "urn:uuid:014a68ec-d691-49e0-b980-91b0d924e570"
                  }
                ],
                "title": "Active Condition 1"
              }
            ],
            "status": "final",
            "subject": {
              "display": "Example Patient",
              "reference": "urn:uuid:970af6c9-5bbd-4067-b6c1-d9b2c823aece"
            },
            "text": {
              "div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"><p><b>Generated Narrative</b></p><div style=\"display: inline-block; background-color: #d9e0e7; padding: 6px; margin: 4px; border: 1px solid #8da1b4; border-radius: 5px; line-height: 60%\"><p style=\"margin-bottom: 0px\">Resource \"17a80a8d-4cf1-4deb-a1fd-2db1130e5f76\" </p></div><p><b>status</b>: final</p><p><b>type</b>: Medical records <span style=\"background: LightGoldenRodYellow; margin: 4px; border: 1px solid khaki\"> (<a href=\"https://loinc.org/\">LOINC</a>#11503-0)</span></p><p><b>encounter</b>: <a href=\"#Encounter_5ce5c83a-000f-47d2-941c-039358cc9112\">See above (urn:uuid:5ce5c83a-000f-47d2-941c-039358cc9112: Example Encounter)</a></p><p><b>date</b>: 2021-10-25T20:16:29-07:00</p><p><b>author</b>: <a href=\"#Practitioner_0820c16d-91de-4dfa-a3a6-f140a516a9bc\">See above (urn:uuid:0820c16d-91de-4dfa-a3a6-f140a516a9bc: Example Practitioner)</a></p><p><b>title</b>: Active Conditions</p><h3>Attesters</h3><table class=\"grid\"><tr><td>-</td><td><b>Mode</b></td><td><b>Time</b></td><td><b>Party</b></td></tr><tr><td>*</td><td>legal</td><td>2021-10-25T20:16:29-07:00</td><td><a href=\"#Practitioner_0820c16d-91de-4dfa-a3a6-f140a516a9bc\">See above (urn:uuid:0820c16d-91de-4dfa-a3a6-f140a516a9bc: Example Practitioner)</a></td></tr></table></div>",
              "status": "generated"
            },
            "title": "Active Conditions",
            "type": {
              "coding": [
                {
                  "code": "11503-0",
                  "system": "http://loinc.org"
                }
              ],
              "text": "Medical records"
            }
          }
        },
        {
          "fullUrl": "urn:uuid:0820c16d-91de-4dfa-a3a6-f140a516a9bc",
          "resource": {
            "id": "0820c16d-91de-4dfa-a3a6-f140a516a9bc",
            "meta": {
              "lastUpdated": "2013-05-05T16:13:03Z"
            },
            "name": [
              {
                "family": "Hancock",
                "given": [
                  "John"
                ]
              }
            ],
            "resourceType": "Practitioner",
            "text": {
              "div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"><p><b>Generated Narrative</b></p><div style=\"display: inline-block; background-color: #d9e0e7; padding: 6px; margin: 4px; border: 1px solid #8da1b4; border-radius: 5px; line-height: 60%\"><p style=\"margin-bottom: 0px\">Resource \"0820c16d-91de-4dfa-a3a6-f140a516a9bc\" Updated \"2013-05-05T16:13:03Z\" </p></div><p><b>name</b>: John Hancock </p></div>",
              "status": "generated"
            }
          }
        },
        {
          "fullUrl": "urn:uuid:970af6c9-5bbd-4067-b6c1-d9b2c823aece",
          "resource": {
            "active": true,
            "id": "970af6c9-5bbd-4067-b6c1-d9b2c823aece",
            "name": [
              {
                "family": "Patient",
                "given": [
                  "CDEX Example"
                ],
                "text": "CDEX Example Patient"
              }
            ],
            "resourceType": "Patient",
            "text": {
              "div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"><p><b>Generated Narrative</b></p><div style=\"display: inline-block; background-color: #d9e0e7; padding: 6px; margin: 4px; border: 1px solid #8da1b4; border-radius: 5px; line-height: 60%\"><p style=\"margin-bottom: 0px\">Resource \"970af6c9-5bbd-4067-b6c1-d9b2c823aece\" </p></div><p><b>active</b>: true</p><p><b>name</b>: CDEX Example Patient</p></div>",
              "status": "generated"
            }
          }
        },
        {
          "fullUrl": "urn:uuid:014a68ec-d691-49e0-b980-91b0d924e570",
          "resource": {
            "asserter": {
              "reference": "urn:uuid:0820c16d-91de-4dfa-a3a6-f140a516a9bc"
            },
            "category": [
              {
                "coding": [
                  {
                    "code": "55607006",
                    "display": "Problem",
                    "system": "http://snomed.info/sct"
                  },
                  {
                    "code": "75326-9",
                    "display": "Problem",
                    "system": "http://loinc.org"
                  }
                ]
              }
            ],
            "clinicalStatus": {
              "coding": [
                {
                  "code": "active",
                  "system": "http://terminology.hl7.org/CodeSystem/condition-clinical"
                }
              ]
            },
            "code": {
              "coding": [
                {
                  "code": "44054006",
                  "display": "Type 2 Diabetes Mellitus",
                  "system": "http://snomed.info/sct"
                }
              ]
            },
            "id": "014a68ec-d691-49e0-b980-91b0d924e570",
            "identifier": [
              {
                "system": "urn:oid:1.3.6.1.4.1.22812.4.111.0.4.1.2.1",
                "value": "1"
              }
            ],
            "onsetDateTime": "2006",
            "resourceType": "Condition",
            "subject": {
              "reference": "urn:uuid:970af6c9-5bbd-4067-b6c1-d9b2c823aece"
            },
            "text": {
              "div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"><p><b>Generated Narrative</b></p><div style=\"display: inline-block; background-color: #d9e0e7; padding: 6px; margin: 4px; border: 1px solid #8da1b4; border-radius: 5px; line-height: 60%\"><p style=\"margin-bottom: 0px\">Resource \"014a68ec-d691-49e0-b980-91b0d924e570\" </p></div><p><b>identifier</b>: id: 1</p><p><b>clinicalStatus</b>: Active <span style=\"background: LightGoldenRodYellow; margin: 4px; border: 1px solid khaki\"> (<a href=\"http://terminology.hl7.org/3.0.0/CodeSystem-condition-clinical.html\">Condition Clinical Status Codes</a>#active)</span></p><p><b>category</b>: Problem <span style=\"background: LightGoldenRodYellow; margin: 4px; border: 1px solid khaki\"> (<a href=\"https://browser.ihtsdotools.org/\">SNOMED CT</a>#55607006; <a href=\"https://loinc.org/\">LOINC</a>#75326-9)</span></p><p><b>code</b>: Type 2 Diabetes Mellitus <span style=\"background: LightGoldenRodYellow; margin: 4px; border: 1px solid khaki\"> (<a href=\"https://browser.ihtsdotools.org/\">SNOMED CT</a>#44054006)</span></p><p><b>subject</b>: <a href=\"#Patient_970af6c9-5bbd-4067-b6c1-d9b2c823aece\">See above (urn:uuid:970af6c9-5bbd-4067-b6c1-d9b2c823aece)</a></p><p><b>onset</b>: 2006-01-01</p><p><b>asserter</b>: <a href=\"#Practitioner_0820c16d-91de-4dfa-a3a6-f140a516a9bc\">See above (urn:uuid:0820c16d-91de-4dfa-a3a6-f140a516a9bc)</a></p></div>",
              "status": "generated"
            }
          }
        },
        {
          "fullUrl": "urn:uuid:5ce5c83a-000f-47d2-941c-039358cc9112",
          "resource": {
            "class": {
              "code": "EMER",
              "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode"
            },
            "id": "5ce5c83a-000f-47d2-941c-039358cc9112",
            "participant": [
              {
                "individual": {
                  "display": "John Hancock",
                  "reference": "urn:uuid:0820c16d-91de-4dfa-a3a6-f140a516a9bc"
                }
              }
            ],
            "period": {
              "end": "2021-10-25T20:16:29-07:00",
              "start": "2021-10-25T20:10:29-07:00"
            },
            "resourceType": "Encounter",
            "serviceProvider": {
              "display": "CDEX Example Organization",
              "reference": "urn:uuid:e37f004b-dc10-422b-b833-cdaa10a055a3"
            },
            "status": "finished",
            "subject": {
              "display": "CDEX Example Patient",
              "reference": "urn:uuid:970af6c9-5bbd-4067-b6c1-d9b2c823aece"
            },
            "text": {
              "div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"><p><b>Generated Narrative</b></p><div style=\"display: inline-block; background-color: #d9e0e7; padding: 6px; margin: 4px; border: 1px solid #8da1b4; border-radius: 5px; line-height: 60%\"><p style=\"margin-bottom: 0px\">Resource \"5ce5c83a-000f-47d2-941c-039358cc9112\" </p></div><p><b>status</b>: finished</p><p><b>class</b>: emergency (Details: http://terminology.hl7.org/CodeSystem/v3-ActCode code EMER = 'emergency', stated as 'null')</p><p><b>type</b>: Unknown (qualifier value) <span style=\"background: LightGoldenRodYellow; margin: 4px; border: 1px solid khaki\"> (<a href=\"https://browser.ihtsdotools.org/\">SNOMED CT</a>#261665006)</span></p><p><b>subject</b>: <a href=\"#Patient_970af6c9-5bbd-4067-b6c1-d9b2c823aece\">See above (urn:uuid:970af6c9-5bbd-4067-b6c1-d9b2c823aece: CDEX Example Patient)</a></p><h3>Participants</h3><table class=\"grid\"><tr><td>-</td><td><b>Individual</b></td></tr><tr><td>*</td><td><a href=\"#Practitioner_0820c16d-91de-4dfa-a3a6-f140a516a9bc\">See above (urn:uuid:0820c16d-91de-4dfa-a3a6-f140a516a9bc: John Hancock)</a></td></tr></table><p><b>period</b>: 2021-10-25T20:10:29-07:00 --> 2021-10-25T20:16:29-07:00</p><p><b>serviceProvider</b>: <a href=\"#Organization_e37f004b-dc10-422b-b833-cdaa10a055a3\">See above (urn:uuid:e37f004b-dc10-422b-b833-cdaa10a055a3: CDEX Example Organization)</a></p></div>",
              "status": "generated"
            },
            "type": [
              {
                "coding": [
                  {
                    "code": "261665006",
                    "display": "Unknown (qualifier value)",
                    "system": "http://snomed.info/sct"
                  }
                ],
                "text": "Unknown (qualifier value)"
              }
            ]
          }
        },
        {
          "fullUrl": "urn:uuid:e37f004b-dc10-422b-b833-cdaa10a055a3",
          "resource": {
            "active": true,
            "address": [
              {
                "city": "Boston",
                "country": "USA",
                "line": [
                  "1 CDEX Lane"
                ],
                "postalCode": "01002",
                "state": "MA"
              }
            ],
            "id": "e37f004b-dc10-422b-b833-cdaa10a055a3",
            "name": "CDEX Example Organization",
            "resourceType": "Organization",
            "telecom": [
              {
                "system": "phone",
                "value": "(+1) 555-555-5555"
              },
              {
                "system": "email",
                "value": "customer-service@example.org"
              }
            ],
            "text": {
              "div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"><p><b>Generated Narrative</b></p><div style=\"display: inline-block; background-color: #d9e0e7; padding: 6px; margin: 4px; border: 1px solid #8da1b4; border-radius: 5px; line-height: 60%\"><p style=\"margin-bottom: 0px\">Resource \"e37f004b-dc10-422b-b833-cdaa10a055a3\" </p></div><p><b>active</b>: true</p><p><b>name</b>: CDEX Example Organization</p><p><b>telecom</b>: ph: (+1) 555-555-5555, <a href=\"mailto:customer-service@example.org\">customer-service@example.org</a></p><p><b>address</b>: 1 CDEX Lane Boston MA 01002 USA </p></div>",
              "status": "generated"
            }
          }
        }
      ],
      "identifier": {
        "system": "urn:ietf:rfc:3986",
        "value": "urn:uuid:c173535e-135e-48e3-ab64-38bacc68dba8"
      },
      "resourceType": "Bundle",
      "timestamp": "2021-10-25T20:16:29-07:00",
      "type": "document",
      "id": "cdex-document-digital-sig-example",
      "meta": {
        "extension": [
          {
            "url": "http://hl7.org/fhir/StructureDefinition/instance-name",
            "valueString": "CDEX Document with Digital Signature Example"
          },
          {
            "url": "http://hl7.org/fhir/StructureDefinition/instance-description",
            "valueMarkdown": "Digital signature example showing how it is used to sign a FHIR Document.  The CDEX use case would be the target resource in response to a Task-based request where an digital signature was required.  If no signature was required, the response would typically be in the form of an individual resource."
          }
        ]
      },
      "signature": {
        "type": [
          {
            "system": "urn:iso-astm:E1762-95:2013",
            "code": "1.2.840.10065.1.12.1.5",
            "display": "Verification Signature"
          }
        ],
        "when": "2021-10-05T22:42:19-07:00",
        "who": {
          "reference": "Practitioner/123"
        },
        "onBehalfOf": {
          "reference": "Organization/123"
        },
        "data": " "
      }
    }

### Receiver/Verifier Steps

1. Remove the `Bundle.signature` element from the Search Bundle resource

- For this example using the python dictionary object from above, but in real life, it would be contained and/or Referenced by TASK over-the-wire. Therefore it would need to be 'decontained' and/or fetched and stored in order to perform these next steps.

    try:
      recd_signature = document_bundle.pop("signature")
    except:
      pass
    recd_signature

    {'type': [{'system': 'urn:iso-astm:E1762-95:2013',
       'code': '1.2.840.10065.1.12.1.5',
       'display': 'Verification Signature'}],
     'when': '2021-10-05T22:42:19-07:00',
     'who': {'reference': 'Practitioner/123'},
     'onBehalfOf': {'reference': 'Organization/123'},
     'data': ' '}

2. Canonicalize the bundle using IETF JSON Canonicalization Scheme (JCS):

- Remove the id and meta elements if present before canonicalization

    document_bundle_id = document_bundle.pop("id") # remove id
    document_bundle_meta = document_bundle.pop("meta") # remove meta
    canonical_bundle = canonicalize(document_bundle)
    canonical_bundle

    b'{"entry":[{"fullUrl":"urn:uuid:17a80a8d-4cf1-4deb-a1fd-2db1130e5f76","resource":{"attester":[{"mode":"legal","party":{"display":"Example Practitioner","reference":"urn:uuid:0820c16d-91de-4dfa-a3a6-f140a516a9bc"},"time":"2021-10-25T20:16:29-07:00"}],"author":[{"display":"Example Practitioner","reference":"urn:uuid:0820c16d-91de-4dfa-a3a6-f140a516a9bc"}],"date":"2021-10-25T20:16:29-07:00","encounter":{"display":"Example Encounter","reference":"urn:uuid:5ce5c83a-000f-47d2-941c-039358cc9112"},"id":"17a80a8d-4cf1-4deb-a1fd-2db1130e5f76","resourceType":"Composition","section":[{"entry":[{"reference":"urn:uuid:014a68ec-d691-49e0-b980-91b0d924e570"}],"title":"Active Condition 1"}],"status":"final","subject":{"display":"Example Patient","reference":"urn:uuid:970af6c9-5bbd-4067-b6c1-d9b2c823aece"},"text":{"div":"<div xmlns=\\"http://www.w3.org/1999/xhtml\\"><p><b>Generated Narrative</b></p><div style=\\"display: inline-block; background-color: #d9e0e7; padding: 6px; margin: 4px; border: 1px solid #8da1b4; border-radius: 5px; line-height: 60%\\"><p style=\\"margin-bottom: 0px\\">Resource \\"17a80a8d-4cf1-4deb-a1fd-2db1130e5f76\\" </p></div><p><b>status</b>: final</p><p><b>type</b>: Medical records <span style=\\"background: LightGoldenRodYellow; margin: 4px; border: 1px solid khaki\\"> (<a href=\\"https://loinc.org/\\">LOINC</a>#11503-0)</span></p><p><b>encounter</b>: <a href=\\"#Encounter_5ce5c83a-000f-47d2-941c-039358cc9112\\">See above (urn:uuid:5ce5c83a-000f-47d2-941c-039358cc9112: Example Encounter)</a></p><p><b>date</b>: 2021-10-25T20:16:29-07:00</p><p><b>author</b>: <a href=\\"#Practitioner_0820c16d-91de-4dfa-a3a6-f140a516a9bc\\">See above (urn:uuid:0820c16d-91de-4dfa-a3a6-f140a516a9bc: Example Practitioner)</a></p><p><b>title</b>: Active Conditions</p><h3>Attesters</h3><table class=\\"grid\\"><tr><td>-</td><td><b>Mode</b></td><td><b>Time</b></td><td><b>Party</b></td></tr><tr><td>*</td><td>legal</td><td>2021-10-25T20:16:29-07:00</td><td><a href=\\"#Practitioner_0820c16d-91de-4dfa-a3a6-f140a516a9bc\\">See above (urn:uuid:0820c16d-91de-4dfa-a3a6-f140a516a9bc: Example Practitioner)</a></td></tr></table></div>","status":"generated"},"title":"Active Conditions","type":{"coding":[{"code":"11503-0","system":"http://loinc.org"}],"text":"Medical records"}}},{"fullUrl":"urn:uuid:0820c16d-91de-4dfa-a3a6-f140a516a9bc","resource":{"id":"0820c16d-91de-4dfa-a3a6-f140a516a9bc","meta":{"lastUpdated":"2013-05-05T16:13:03Z"},"name":[{"family":"Hancock","given":["John"]}],"resourceType":"Practitioner","text":{"div":"<div xmlns=\\"http://www.w3.org/1999/xhtml\\"><p><b>Generated Narrative</b></p><div style=\\"display: inline-block; background-color: #d9e0e7; padding: 6px; margin: 4px; border: 1px solid #8da1b4; border-radius: 5px; line-height: 60%\\"><p style=\\"margin-bottom: 0px\\">Resource \\"0820c16d-91de-4dfa-a3a6-f140a516a9bc\\" Updated \\"2013-05-05T16:13:03Z\\" </p></div><p><b>name</b>: John Hancock </p></div>","status":"generated"}}},{"fullUrl":"urn:uuid:970af6c9-5bbd-4067-b6c1-d9b2c823aece","resource":{"active":true,"id":"970af6c9-5bbd-4067-b6c1-d9b2c823aece","name":[{"family":"Patient","given":["CDEX Example"],"text":"CDEX Example Patient"}],"resourceType":"Patient","text":{"div":"<div xmlns=\\"http://www.w3.org/1999/xhtml\\"><p><b>Generated Narrative</b></p><div style=\\"display: inline-block; background-color: #d9e0e7; padding: 6px; margin: 4px; border: 1px solid #8da1b4; border-radius: 5px; line-height: 60%\\"><p style=\\"margin-bottom: 0px\\">Resource \\"970af6c9-5bbd-4067-b6c1-d9b2c823aece\\" </p></div><p><b>active</b>: true</p><p><b>name</b>: CDEX Example Patient</p></div>","status":"generated"}}},{"fullUrl":"urn:uuid:014a68ec-d691-49e0-b980-91b0d924e570","resource":{"asserter":{"reference":"urn:uuid:0820c16d-91de-4dfa-a3a6-f140a516a9bc"},"category":[{"coding":[{"code":"55607006","display":"Problem","system":"http://snomed.info/sct"},{"code":"75326-9","display":"Problem","system":"http://loinc.org"}]}],"clinicalStatus":{"coding":[{"code":"active","system":"http://terminology.hl7.org/CodeSystem/condition-clinical"}]},"code":{"coding":[{"code":"44054006","display":"Type 2 Diabetes Mellitus","system":"http://snomed.info/sct"}]},"id":"014a68ec-d691-49e0-b980-91b0d924e570","identifier":[{"system":"urn:oid:1.3.6.1.4.1.22812.4.111.0.4.1.2.1","value":"1"}],"onsetDateTime":"2006","resourceType":"Condition","subject":{"reference":"urn:uuid:970af6c9-5bbd-4067-b6c1-d9b2c823aece"},"text":{"div":"<div xmlns=\\"http://www.w3.org/1999/xhtml\\"><p><b>Generated Narrative</b></p><div style=\\"display: inline-block; background-color: #d9e0e7; padding: 6px; margin: 4px; border: 1px solid #8da1b4; border-radius: 5px; line-height: 60%\\"><p style=\\"margin-bottom: 0px\\">Resource \\"014a68ec-d691-49e0-b980-91b0d924e570\\" </p></div><p><b>identifier</b>: id: 1</p><p><b>clinicalStatus</b>: Active <span style=\\"background: LightGoldenRodYellow; margin: 4px; border: 1px solid khaki\\"> (<a href=\\"http://terminology.hl7.org/3.0.0/CodeSystem-condition-clinical.html\\">Condition Clinical Status Codes</a>#active)</span></p><p><b>category</b>: Problem <span style=\\"background: LightGoldenRodYellow; margin: 4px; border: 1px solid khaki\\"> (<a href=\\"https://browser.ihtsdotools.org/\\">SNOMED CT</a>#55607006; <a href=\\"https://loinc.org/\\">LOINC</a>#75326-9)</span></p><p><b>code</b>: Type 2 Diabetes Mellitus <span style=\\"background: LightGoldenRodYellow; margin: 4px; border: 1px solid khaki\\"> (<a href=\\"https://browser.ihtsdotools.org/\\">SNOMED CT</a>#44054006)</span></p><p><b>subject</b>: <a href=\\"#Patient_970af6c9-5bbd-4067-b6c1-d9b2c823aece\\">See above (urn:uuid:970af6c9-5bbd-4067-b6c1-d9b2c823aece)</a></p><p><b>onset</b>: 2006-01-01</p><p><b>asserter</b>: <a href=\\"#Practitioner_0820c16d-91de-4dfa-a3a6-f140a516a9bc\\">See above (urn:uuid:0820c16d-91de-4dfa-a3a6-f140a516a9bc)</a></p></div>","status":"generated"}}},{"fullUrl":"urn:uuid:5ce5c83a-000f-47d2-941c-039358cc9112","resource":{"class":{"code":"EMER","system":"http://terminology.hl7.org/CodeSystem/v3-ActCode"},"id":"5ce5c83a-000f-47d2-941c-039358cc9112","participant":[{"individual":{"display":"John Hancock","reference":"urn:uuid:0820c16d-91de-4dfa-a3a6-f140a516a9bc"}}],"period":{"end":"2021-10-25T20:16:29-07:00","start":"2021-10-25T20:10:29-07:00"},"resourceType":"Encounter","serviceProvider":{"display":"CDEX Example Organization","reference":"urn:uuid:e37f004b-dc10-422b-b833-cdaa10a055a3"},"status":"finished","subject":{"display":"CDEX Example Patient","reference":"urn:uuid:970af6c9-5bbd-4067-b6c1-d9b2c823aece"},"text":{"div":"<div xmlns=\\"http://www.w3.org/1999/xhtml\\"><p><b>Generated Narrative</b></p><div style=\\"display: inline-block; background-color: #d9e0e7; padding: 6px; margin: 4px; border: 1px solid #8da1b4; border-radius: 5px; line-height: 60%\\"><p style=\\"margin-bottom: 0px\\">Resource \\"5ce5c83a-000f-47d2-941c-039358cc9112\\" </p></div><p><b>status</b>: finished</p><p><b>class</b>: emergency (Details: http://terminology.hl7.org/CodeSystem/v3-ActCode code EMER = \'emergency\', stated as \'null\')</p><p><b>type</b>: Unknown (qualifier value) <span style=\\"background: LightGoldenRodYellow; margin: 4px; border: 1px solid khaki\\"> (<a href=\\"https://browser.ihtsdotools.org/\\">SNOMED CT</a>#261665006)</span></p><p><b>subject</b>: <a href=\\"#Patient_970af6c9-5bbd-4067-b6c1-d9b2c823aece\\">See above (urn:uuid:970af6c9-5bbd-4067-b6c1-d9b2c823aece: CDEX Example Patient)</a></p><h3>Participants</h3><table class=\\"grid\\"><tr><td>-</td><td><b>Individual</b></td></tr><tr><td>*</td><td><a href=\\"#Practitioner_0820c16d-91de-4dfa-a3a6-f140a516a9bc\\">See above (urn:uuid:0820c16d-91de-4dfa-a3a6-f140a516a9bc: John Hancock)</a></td></tr></table><p><b>period</b>: 2021-10-25T20:10:29-07:00 --> 2021-10-25T20:16:29-07:00</p><p><b>serviceProvider</b>: <a href=\\"#Organization_e37f004b-dc10-422b-b833-cdaa10a055a3\\">See above (urn:uuid:e37f004b-dc10-422b-b833-cdaa10a055a3: CDEX Example Organization)</a></p></div>","status":"generated"},"type":[{"coding":[{"code":"261665006","display":"Unknown (qualifier value)","system":"http://snomed.info/sct"}],"text":"Unknown (qualifier value)"}]}},{"fullUrl":"urn:uuid:e37f004b-dc10-422b-b833-cdaa10a055a3","resource":{"active":true,"address":[{"city":"Boston","country":"USA","line":["1 CDEX Lane"],"postalCode":"01002","state":"MA"}],"id":"e37f004b-dc10-422b-b833-cdaa10a055a3","name":"CDEX Example Organization","resourceType":"Organization","telecom":[{"system":"phone","value":"(+1) 555-555-5555"},{"system":"email","value":"customer-service@example.org"}],"text":{"div":"<div xmlns=\\"http://www.w3.org/1999/xhtml\\"><p><b>Generated Narrative</b></p><div style=\\"display: inline-block; background-color: #d9e0e7; padding: 6px; margin: 4px; border: 1px solid #8da1b4; border-radius: 5px; line-height: 60%\\"><p style=\\"margin-bottom: 0px\\">Resource \\"e37f004b-dc10-422b-b833-cdaa10a055a3\\" </p></div><p><b>active</b>: true</p><p><b>name</b>: CDEX Example Organization</p><p><b>telecom</b>: ph: (+1) 555-555-5555, <a href=\\"mailto:customer-service@example.org\\">customer-service@example.org</a></p><p><b>address</b>: 1 CDEX Lane Boston MA 01002 USA </p></div>","status":"generated"}}}],"identifier":{"system":"urn:ietf:rfc:3986","value":"urn:uuid:c173535e-135e-48e3-ab64-38bacc68dba8"},"resourceType":"Bundle","timestamp":"2021-10-25T20:16:29-07:00","type":"document"}'

3. Transform canonicalize Bundle to a base64 format using the Base64-URL algorithm.

    from base64 import urlsafe_b64encode
    recd_b64_canonical_bundle  = urlsafe_b64encode(canonical_bundle).decode()
    recd_b64_canonical_bundle = recd_b64_canonical_bundle.replace("=","")  #remove padding since decode package doesn't use them
    recd_b64_canonical_bundle

    ' '

4. Get the base64 encoded JWS from the `Bundle.signature.data` element

    recd_b64_jws = recd_signature['data']
    recd_b64_jws

    ' '

5. Base64 decode the encoded JWS

note the signature is displayed with the parts labeled and separated with line breaks for easier viewing

    from base64 import b64decode
    recd_jws = b64decode(recd_b64_jws.encode()).decode()
    for i,j in enumerate(recd_jws.split('.')):
        print(f'{labels[i]}:')
        print(f'{j}')
        print()

    header:

    payload:

    signature:

6. reattach the payload - the base64 encoded Bundle - into the JWS payload element.

note the signature is displayed with the parts labeled and separated with line breaks for easier viewing

    split_sig = recd_jws.split('.')
    split_sig[1] = recd_b64_canonical_bundle
    recd_jws = '.'.join(split_sig)
    for i,j in enumerate(recd_jws.split('.')):
        print(f'{labels[i]}:')
        print(f'{j}')
        print()

    header:

    payload:

    signature:

7. Obtain public Key from the first certificate in JWS header `"x5c"` key

- base64 decode the key value
- Verify Issuer, Validity Dates, Subject,and KeyUsage of certificate,
- Get the “Subject Public Key Info” from the cert to verify the signature

    recd_header = jws.get_unverified_header(recd_jws)
    recd_header

    {'alg': 'RS256',
     'kty': 'RS',
     'typ': 'JWT',
     'x5c': [' ']}

    recd_cert = b64decode(recd_header['x5c'][0])
    with open('recd_cert.der', 'wb') as f:
        f.write(recd_cert)
    !openssl x509 -in recd_cert.der -inform DER -text

    Certificate:
        Data:
            Version: 3 (0x2)
            Serial Number: 16322561221100825744 (0xe28562f33047ec90)
        Signature Algorithm: sha256WithRSAEncryption
            Issuer: C=US, ST=California, L=Sausalito, O=HealtheData1, CN=Eric Haas, DVM/emailAddress=ehaas@healthedata1.org
            Validity
                Not Before: Oct 27 17:42:04 2021 GMT
                Not After : Oct 22 17:42:04 2022 GMT
            Subject: C=US, ST=California, L=Sausalito, O=HealtheData1, CN=Eric Haas, DVM/emailAddress=ehaas@healthedata1.org
            Subject Public Key Info:
                Public Key Algorithm: rsaEncryption
                    Public-Key: (3072 bit)
                    Modulus:
                        00:e9:29:c4:a4:a0:03:3a:b1:6d:b5:fa:f5:93:78:
                        85:4e:1b:1d:74:31:66:ac:43:2e:d5:1e:27:7a:cf:
                        2a:97:00:13:3e:ce:77:c1:9d:77:a7:c9:4d:23:d4:
                        54:ef:3e:64:5f:38:3a:0e:0d:75:6e:3d:4c:03:a2:
                        68:42:1e:1f:9b:72:55:bd:28:cd:a8:e7:ad:dc:c5:
                        12:84:bc:19:da:1e:bb:23:c3:9c:8d:9b:13:b9:62:
                        31:11:6e:1b:47:75:07:aa:92:d7:70:dd:56:04:45:
                        1f:47:a3:12:ce:dc:59:2c:cd:1d:bd:d8:74:c1:e3:
                        15:b7:c9:69:55:de:04:e4:31:0a:33:3d:27:09:28:
                        7d:db:1b:c3:ea:ab:a0:18:3c:9e:c2:e1:80:48:95:
                        44:9d:04:c5:65:de:a9:de:11:f8:3b:7e:ec:62:15:
                        f5:e8:7d:d4:d5:9b:ba:cc:8a:21:bb:5f:dc:f8:dc:
                        f7:e2:96:a6:9e:8a:c7:e6:b5:1c:40:95:1c:04:35:
                        7a:c7:dc:eb:ce:0c:fc:8b:d2:b4:e7:1b:c0:ac:6c:
                        05:d8:54:83:26:75:d1:de:e1:91:7d:a6:58:7d:e6:
                        c8:f8:a4:c4:e1:2e:d7:09:5f:fa:3d:5c:72:e3:87:
                        b1:26:67:28:09:1d:61:10:ab:83:f0:17:06:5d:99:
                        b7:1f:84:29:8e:af:cf:07:f0:16:d4:ae:ef:fb:57:
                        ac:db:b0:6d:4d:d4:25:a5:9d:d9:5b:57:39:cb:fb:
                        72:0c:3a:bf:24:5d:a1:dc:6a:7a:9f:72:48:05:57:
                        81:2b:9d:f8:c5:26:ad:4e:21:a0:26:b0:c8:fc:e7:
                        13:24:8f:25:cb:c9:c2:cb:fe:ee:67:da:8e:81:83:
                        dd:ff:51:17:ea:b8:ea:12:20:63:82:47:6e:43:69:
                        9c:e9:c3:69:37:b3:ba:04:f5:d3:30:11:65:ed:7d:
                        78:18:b6:1d:9b:96:3c:b9:b4:51:f4:1a:3a:4e:93:
                        1d:3b:8f:b6:53:e4:79:f1:9e:5b
                    Exponent: 65537 (0x10001)
            X509v3 extensions:
                X509v3 Basic Constraints:
                    CA:TRUE
                X509v3 Key Usage:
                    Digital Signature, Non Repudiation, Key Encipherment
                X509v3 Subject Alternative Name:
                    DNS:www.healthedatainc.com
        Signature Algorithm: sha256WithRSAEncryption
             0a:e3:14:36:af:5a:cb:ef:9e:e5:80:bb:40:53:bd:e2:b7:f3:
             c4:64:27:17:71:a4:95:93:40:5e:62:2b:ec:f5:46:76:21:98:
             d8:64:f1:ff:d4:6d:1c:2c:13:2b:39:0b:fb:2b:ca:a2:37:99:
             f5:d5:4a:f3:0a:c6:56:24:64:3b:f8:d4:c9:9f:8a:71:64:68:
             91:48:ec:e7:d9:dc:24:64:4c:49:24:71:b5:e0:90:ba:3b:78:
             85:fd:be:fe:a5:7e:7f:6b:0c:42:d1:2b:c0:f1:37:d2:f6:ea:
             45:85:0d:34:d0:55:11:0a:5a:43:1f:da:70:90:d4:bf:db:fb:
             b2:31:e2:24:3a:97:c1:0f:ab:ce:3f:79:88:70:08:69:e1:07:
             a8:5f:cc:b3:6d:a9:d9:b7:99:ba:ab:c8:40:a7:8c:97:eb:2f:
             56:a1:ed:8a:ec:d6:9c:5e:14:e9:52:26:a6:4a:f8:6c:79:7b:
             7a:05:7d:1f:a9:7a:4f:64:8c:92:3e:aa:0d:4e:5e:f4:d8:34:
             66:52:d3:b6:8b:2c:84:12:e6:a2:91:7b:7b:b1:f2:ad:31:00:
             99:f3:8f:29:07:b4:12:0f:44:da:ea:f3:c6:a0:6e:1b:9e:24:
             e7:41:b6:27:41:62:3e:c4:09:02:11:62:34:6c:12:83:84:b7:
             1f:25:43:1b:bb:9e:29:dd:0b:f7:7c:0a:38:d3:98:1a:f3:0a:
             8b:30:87:07:ea:4a:bc:43:09:a1:9f:32:f6:e8:81:f8:71:57:
             72:9f:51:68:9a:89:f7:b1:e9:65:31:2f:fa:58:82:a7:63:d2:
             5f:37:0a:d2:bd:b9:49:cc:a3:17:a7:4b:a2:e2:b6:48:1d:f4:
             c4:0b:c9:f2:d1:39:f3:8f:a3:a9:0e:82:19:e7:14:f5:78:ef:
             94:08:ee:25:d0:ab:0d:e5:4f:b2:39:27:ec:e3:d7:1b:ef:17:
             65:4e:f3:a8:76:4d:99:75:f5:61:8e:07:e6:b8:04:27:8f:25:
             ad:4a:cf:dc:8f:11
    -----BEGIN CERTIFICATE-----
    MIIE3zCCA0egAwIBAgIJAOKFYvMwR+yQMA0GCSqGSIb3DQEBCwUAMIGNMQswCQYD
    VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJU2F1c2FsaXRv
    MRUwEwYDVQQKDAxIZWFsdGhlRGF0YTExFzAVBgNVBAMMDkVyaWMgSGFhcywgRFZN
    MSUwIwYJKoZIhvcNAQkBFhZlaGFhc0BoZWFsdGhlZGF0YTEub3JnMB4XDTIxMTAy
    NzE3NDIwNFoXDTIyMTAyMjE3NDIwNFowgY0xCzAJBgNVBAYTAlVTMRMwEQYDVQQI
    DApDYWxpZm9ybmlhMRIwEAYDVQQHDAlTYXVzYWxpdG8xFTATBgNVBAoMDEhlYWx0
    aGVEYXRhMTEXMBUGA1UEAwwORXJpYyBIYWFzLCBEVk0xJTAjBgkqhkiG9w0BCQEW
    FmVoYWFzQGhlYWx0aGVkYXRhMS5vcmcwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAw
    ggGKAoIBgQDpKcSkoAM6sW21+vWTeIVOGx10MWasQy7VHid6zyqXABM+znfBnXen
    yU0j1FTvPmRfODoODXVuPUwDomhCHh+bclW9KM2o563cxRKEvBnaHrsjw5yNmxO5
    YjERbhtHdQeqktdw3VYERR9HoxLO3FkszR292HTB4xW3yWlV3gTkMQozPScJKH3b
    G8Pqq6AYPJ7C4YBIlUSdBMVl3qneEfg7fuxiFfXofdTVm7rMiiG7X9z43Pfilqae
    isfmtRxAlRwENXrH3OvODPyL0rTnG8CsbAXYVIMmddHe4ZF9plh95sj4pMThLtcJ
    X/o9XHLjh7EmZygJHWEQq4PwFwZdmbcfhCmOr88H8BbUru/7V6zbsG1N1CWlndlb
    VznL+3IMOr8kXaHcanqfckgFV4ErnfjFJq1OIaAmsMj85xMkjyXLycLL/u5n2o6B
    g93/URfquOoSIGOCR25DaZzpw2k3s7oE9dMwEWXtfXgYth2bljy5tFH0GjpOkx07
    j7ZT5HnxnlsCAwEAAaNAMD4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCBeAwIQYD
    VR0RBBowGIIWd3d3LmhlYWx0aGVkYXRhaW5jLmNvbTANBgkqhkiG9w0BAQsFAAOC
    AYEACuMUNq9ay++e5YC7QFO94rfzxGQnF3GklZNAXmIr7PVGdiGY2GTx/9RtHCwT
    KzkL+yvKojeZ9dVK8wrGViRkO/jUyZ+KcWRokUjs59ncJGRMSSRxteCQujt4hf2+
    /qV+f2sMQtErwPE30vbqRYUNNNBVEQpaQx/acJDUv9v7sjHiJDqXwQ+rzj95iHAI
    aeEHqF/Ms22p2beZuqvIQKeMl+svVqHtiuzWnF4U6VImpkr4bHl7egV9H6l6T2SM
    kj6qDU5e9Ng0ZlLTtosshBLmopF7e7HyrTEAmfOPKQe0Eg9E2urzxqBuG54k50G2
    J0FiPsQJAhFiNGwSg4S3HyVDG7ueKd0L93wKONOYGvMKizCHB+pKvEMJoZ8y9uiB
    +HFXcp9RaJqJ97HpZTEv+liCp2PSXzcK0r25ScyjF6dLouK2SB30xAvJ8tE584+j
    qQ6CGecU9XjvlAjuJdCrDeVPsjkn7OPXG+8XZU7zqHZNmXX1YY4H5rgEJ48lrUrP
    3I8R
    -----END CERTIFICATE-----

10. Verify Signature using the public key or the X.509 Certificate

Alternatively:

1. visit https://jwt.io.
2. At the top of the page, select "RS256" for the algorithm.
3. Paste the JWS value printed below into the “Encoded” field.
4. The plaintext JWT will be displayed in the “Decoded:Payload” field.
5. The X509 Cert above will appear in the "Verify Signature" box.
6. If verified, a “Signature Verified” message will appear in the bottom left hand corner.

    recd_jws

    ' . . '

    !openssl x509 -in recd_cert.der -inform DER -pubkey -noout > recd-public-key.pem
    with open('recd-public-key.pem') as f:
    <pre style="border:0; overflow-wrap:break-word;">
    pem_public = f.read()
    </pre>
    pem_public

    '-----BEGIN PUBLIC KEY-----\nMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEA6SnEpKADOrFttfr1k3iF\nThsddDFmrEMu1R4nes8qlwATPs53wZ13p8lNI9RU7z5kXzg6Dg11bj1MA6JoQh4f\nm3JVvSjNqOet3MUShLwZ2h67I8OcjZsTuWIxEW4bR3UHqpLXcN1WBEUfR6MSztxZ\nLM0dvdh0weMVt8lpVd4E5DEKMz0nCSh92xvD6qugGDyewuGASJVEnQTFZd6p3hH4\nO37sYhX16H3U1Zu6zIohu1/c+Nz34pamnorH5rUcQJUcBDV6x9zrzgz8i9K05xvA\nrGwF2FSDJnXR3uGRfaZYfebI+KTE4S7XCV/6PVxy44exJmcoCR1hEKuD8BcGXZm3\nH4Qpjq/PB/AW1K7v+1es27BtTdQlpZ3ZW1c5y/tyDDq/JF2h3Gp6n3JIBVeBK534\nxSatTiGgJrDI/OcTJI8ly8nCy/7uZ9qOgYPd/1EX6rjqEiBjgkduQ2mc6cNpN7O6\nBPXTMBFl7X14GLYdm5Y8ubRR9Bo6TpMdO4+2U+R58Z5bAgMBAAE=\n-----END PUBLIC KEY-----\n'

    try:
        verify = jws.verify(recd_jws, pem_public , algorithms=['RS256'])
        print('#     #                                                ### ')
        print('#     #  ######  #####   #  ######  #  ######  #####   ### ')
        print('#     #  #       #    #  #  #       #  #       #    #  ### ')
        print('#     #  #####   #    #  #  #####   #  #####   #    #   #  ')
        print(' #   #   #       #####   #  #       #  #       #    #      ')
        print('  # #    #       #   #   #  #       #  #       #    #  ### ')
        print('   #     ######  #    #  #  #       #  ######  #####   ### ')
        print('                                                           ')

    except Exception as e:
        print('#    #   ####   #####      #    #  ######  #####   #  ######  #  ######  #####       ###          #   ')
        print('##   #  #    #    #        #    #  #       #    #  #  #       #  #       #    #       #          #    ')
        print('# #  #  #    #    #        #    #  #####   #    #  #  #####   #  #####   #    #           #####  #    ')
        print('#  # #  #    #    #        #    #  #       #####   #  #       #  #       #    #       #          #    ')
        print('#   ##  #    #    #         #  #   #       #   #   #  #       #  #       #    #      ###          #   ')
        print('#    #   ####     #          ##    ######  #    #  #  #       #  ######  #####        #            ## ')
        print('                ')
        print(f"not verified: {e}")

    #     #                                                ###
    #     #  ######  #####   #  ######  #  ######  #####   ###
    #     #  #       #    #  #  #       #  #       #    #  ###
    #     #  #####   #    #  #  #####   #  #####   #    #   #
     #   #   #       #####   #  #       #  #       #    #
      # #    #       #   #   #  #       #  #       #    #  ###
       #     ######  #    #  #  #       #  ######  #####   ###