7. The SZTP Bootstrap Server API
This section defines the API for bootstrap servers. The API is defined as that produced by a RESTCONF [RFC8040] server that supports the YANG 1.1 [RFC7950] module defined in this section.7.1. API Overview
The following tree diagram provides an overview for the bootstrap server RESTCONF API. module: ietf-sztp-bootstrap-server rpcs: +---x get-bootstrapping-data | +---w input | | +---w signed-data-preferred? empty | | +---w hw-model? string | | +---w os-name? string | | +---w os-version? string | | +---w nonce? binary | +--ro output | +--ro reporting-level? enumeration {onboarding-server}? | +--ro conveyed-information cms | +--ro owner-certificate? cms | +--ro ownership-voucher? cms +---x report-progress {onboarding-server}? +---w input +---w progress-type enumeration +---w message? string +---w ssh-host-keys | +---w ssh-host-key* [] | +---w algorithm string | +---w key-data binary +---w trust-anchor-certs +---w trust-anchor-cert* cms
7.2. Example Usage
This section presents three examples illustrating the bootstrap server's API. Two examples are provided for the "get-bootstrapping- data" RPC (one to an untrusted bootstrap server and the other to a trusted bootstrap server), and one example is provided for the "report-progress" RPC. The following example illustrates a device using the API to fetch its bootstrapping data from an untrusted bootstrap server. In this example, the device sends the "signed-data-preferred" input parameter and receives signed data in the response. REQUEST [Note: '\' line wrapping for formatting only] POST /restconf/operations/ietf-sztp-bootstrap-server:get-bootstrappi\ ng-data HTTP/1.1 HOST: example.com Content-Type: application/yang.data+xml <input xmlns="urn:ietf:params:xml:ns:yang:ietf-sztp-bootstrap-server"> <signed-data-preferred/> </input> RESPONSE HTTP/1.1 200 OK Date: Sat, 31 Oct 2015 17:02:40 GMT Server: example-server Content-Type: application/yang.data+xml <output xmlns="urn:ietf:params:xml:ns:yang:ietf-sztp-bootstrap-server"> <conveyed-information>base64encodedvalue==</conveyed-information> <owner-certificate>base64encodedvalue==</owner-certificate> <ownership-voucher>base64encodedvalue==</ownership-voucher> </output>
The following example illustrates a device using the API to fetch its bootstrapping data from a trusted bootstrap server. In this example, the device sends additional input parameters to the bootstrap server, which it may use when formulating its response to the device. REQUEST [Note: '\' line wrapping for formatting only] POST /restconf/operations/ietf-sztp-bootstrap-server:get-bootstrappi\ ng-data HTTP/1.1 HOST: example.com Content-Type: application/yang.data+xml <input xmlns="urn:ietf:params:xml:ns:yang:ietf-sztp-bootstrap-server"> <hw-model>model-x</hw-model> <os-name>vendor-os</os-name> <os-version>17.3R2.1</os-version> <nonce>extralongbase64encodedvalue=</nonce> </input> RESPONSE HTTP/1.1 200 OK Date: Sat, 31 Oct 2015 17:02:40 GMT Server: example-server Content-Type: application/yang.data+xml <output xmlns="urn:ietf:params:xml:ns:yang:ietf-sztp-bootstrap-server"> <reporting-level>verbose</reporting-level> <conveyed-information>base64encodedvalue==</conveyed-information> </output>
The following example illustrates a device using the API to post a progress report to a bootstrap server. Illustrated below is the "bootstrap-complete" message, but the device may send other progress reports to the server while bootstrapping. In this example, the device is sending both its SSH host keys and a TLS server certificate, which the bootstrap server may, for example, pass to an NMS, as discussed in Appendix C.3. REQUEST [Note: '\' line wrapping for formatting only] POST /restconf/operations/ietf-sztp-bootstrap-server:report-progress\ HTTP/1.1 HOST: example.com Content-Type: application/yang.data+xml <input xmlns="urn:ietf:params:xml:ns:yang:ietf-sztp-bootstrap-server"> <progress-type>bootstrap-complete</progress-type> <message>example message</message> <ssh-host-keys> <ssh-host-key> <algorithm>ssh-rsa</algorithm> <key-data>base64encodedvalue==</key-data> </ssh-host-key> <ssh-host-key> <algorithm>rsa-sha2-256</algorithm> <key-data>base64encodedvalue==</key-data> </ssh-host-key> </ssh-host-keys> <trust-anchor-certs> <trust-anchor-cert>base64encodedvalue==</trust-anchor-cert> </trust-anchor-certs> </input> RESPONSE HTTP/1.1 204 No Content Date: Sat, 31 Oct 2015 17:02:40 GMT Server: example-server
7.3. YANG Module
The bootstrap server's device-facing API is normatively defined by the YANG module defined in this section. This module uses data types defined in [RFC4253], [RFC5652], [RFC5280], and [RFC8366]; uses an encoding defined in [ITU.X690.2015]; and makes a reference to [RFC4250], [RFC6187], and [Std-802.1AR]. <CODE BEGINS> file "ietf-sztp-bootstrap-server@2019-04-30.yang" module ietf-sztp-bootstrap-server { yang-version 1.1; namespace "urn:ietf:params:xml:ns:yang:ietf-sztp-bootstrap-server"; prefix sztp-svr; organization "IETF NETCONF (Network Configuration) Working Group"; contact "WG Web: <https://datatracker.ietf.org/wg/netconf/> WG List: <mailto:netconf@ietf.org> Author: Kent Watsen <mailto:kent+ietf@watsen.net>"; description "This module defines an interface for bootstrap servers, as defined by RFC 8572 ('Secure Zero Touch Provisioning (SZTP)'). The key words 'MUST', 'MUST NOT', 'REQUIRED', 'SHALL', 'SHALL NOT', 'SHOULD', 'SHOULD NOT', 'RECOMMENDED', 'NOT RECOMMENDED', 'MAY', and 'OPTIONAL' in this document are to be interpreted as described in BCP 14 (RFC 2119) (RFC 8174) when, and only when, they appear in all capitals, as shown here. Copyright (c) 2019 IETF Trust and the persons identified as authors of the code. All rights reserved. Redistribution and use in source and binary forms, with or without modification, is permitted pursuant to, and subject to the license terms contained in, the Simplified BSD License set forth in Section 4.c of the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info). This version of this YANG module is part of RFC 8572; see the RFC itself for full legal notices."; revision 2019-04-30 { description
"Initial version"; reference "RFC 8572: Secure Zero Touch Provisioning (SZTP)"; } // features feature redirect-server { description "The server supports being a 'redirect server'."; } feature onboarding-server { description "The server supports being an 'onboarding server'."; } // typedefs typedef cms { type binary; description "A CMS structure, as specified in RFC 5652, encoded using ASN.1 distinguished encoding rules (DER), as specified in ITU-T X.690."; reference "RFC 5652: Cryptographic Message Syntax (CMS) ITU-T X.690: Information technology - ASN.1 encoding rules: Specification of Basic Encoding Rules (BER), Canonical Encoding Rules (CER) and Distinguished Encoding Rules (DER)"; } // RPCs rpc get-bootstrapping-data { description "This RPC enables a device, as identified by the RESTCONF username, to obtain bootstrapping data that has been made available for it."; input { leaf signed-data-preferred { type empty; description "This optional input parameter enables a device to communicate to the bootstrap server that it prefers
to receive signed data. Devices SHOULD always send this parameter when the bootstrap server is untrusted. Upon receiving this input parameter, the bootstrap server MUST return either signed data or unsigned redirect information; the bootstrap server MUST NOT return unsigned onboarding information."; } leaf hw-model { type string; description "This optional input parameter enables a device to communicate to the bootstrap server its vendor-specific hardware model number. This parameter may be needed, for instance, when a device's IDevID certificate does not include the 'hardwareModelName' value in its subjectAltName field, as is allowed by 802.1AR."; reference "IEEE 802.1AR: IEEE Standard for Local and metropolitan area networks - Secure Device Identity"; } leaf os-name { type string; description "This optional input parameter enables a device to communicate to the bootstrap server the name of its operating system. This parameter may be useful if the device, as identified by its serial number, can run more than one type of operating system (e.g., on a white-box system."; } leaf os-version { type string; description "This optional input parameter enables a device to communicate to the bootstrap server the version of its operating system. This parameter may be used by a bootstrap server to return an operating-system-specific response to the device, thus negating the need for a potentially expensive boot image update."; } leaf nonce { type binary { length "16..32"; } description "This optional input parameter enables a device to communicate to the bootstrap server a nonce value.
This may be especially useful for devices lacking an accurate clock, as then the bootstrap server can dynamically obtain from the manufacturer a voucher with the nonce value in it, as described in RFC 8366."; reference "RFC 8366: A Voucher Artifact for Bootstrapping Protocols"; } } output { leaf reporting-level { if-feature "onboarding-server"; type enumeration { enum minimal { description "Send just the progress reports required by RFC 8572."; reference "RFC 8572: Secure Zero Touch Provisioning (SZTP)"; } enum verbose { description "Send additional progress reports that might help troubleshooting an SZTP bootstrapping issue."; } } default "minimal"; description "Specifies the reporting level for progress reports the bootstrap server would like to receive when processing onboarding information. Progress reports are not sent when processing redirect information or when the bootstrap server is untrusted (e.g., device sent the '<signed-data-preferred>' input parameter)."; } leaf conveyed-information { type cms; mandatory true; description "An SZTP conveyed information artifact, as described in Section 3.1 of RFC 8572."; reference "RFC 8572: Secure Zero Touch Provisioning (SZTP)"; } leaf owner-certificate { type cms; must '../ownership-voucher' { description
"An ownership voucher must be present whenever an owner certificate is presented."; } description "An owner certificate artifact, as described in Section 3.2 of RFC 8572. This leaf is optional because it is only needed when the conveyed information artifact is signed."; reference "RFC 8572: Secure Zero Touch Provisioning (SZTP)"; } leaf ownership-voucher { type cms; must '../owner-certificate' { description "An owner certificate must be present whenever an ownership voucher is presented."; } description "An ownership voucher artifact, as described by Section 3.3 of RFC 8572. This leaf is optional because it is only needed when the conveyed information artifact is signed."; reference "RFC 8572: Secure Zero Touch Provisioning (SZTP)"; } } } rpc report-progress { if-feature "onboarding-server"; description "This RPC enables a device, as identified by the RESTCONF username, to report its bootstrapping progress to the bootstrap server. This RPC is expected to be used when the device obtains onboarding-information from a trusted bootstrap server."; input { leaf progress-type { type enumeration { enum bootstrap-initiated { description "Indicates that the device just used the 'get-bootstrapping-data' RPC. The 'message' node below MAY contain any additional information that the manufacturer thinks might be useful."; } enum parsing-initiated {
description "Indicates that the device is about to start parsing the onboarding information. This progress type is only for when parsing is implemented as a distinct step."; } enum parsing-warning { description "Indicates that the device had a non-fatal error when parsing the response from the bootstrap server. The 'message' node below SHOULD indicate the specific warning that occurred."; } enum parsing-error { description "Indicates that the device encountered a fatal error when parsing the response from the bootstrap server. For instance, this could be due to malformed encoding, the device expecting signed data when only unsigned data is provided, the ownership voucher not listing the device's serial number, or because the signature didn't match. The 'message' node below SHOULD indicate the specific error. This progress type also indicates that the device has abandoned trying to bootstrap off this bootstrap server."; } enum parsing-complete { description "Indicates that the device successfully completed parsing the onboarding information. This progress type is only for when parsing is implemented as a distinct step."; } enum boot-image-initiated { description "Indicates that the device is about to start processing the boot image information."; } enum boot-image-warning { description "Indicates that the device encountered a non-fatal error condition when trying to install a boot image. A possible reason might include a need to reformat a partition causing loss of data. The 'message' node below SHOULD indicate any warning messages that were generated."; } enum boot-image-error {
description "Indicates that the device encountered an error when trying to install a boot image, which could be for reasons such as a file server being unreachable, file not found, signature mismatch, etc. The 'message' node SHOULD indicate the specific error that occurred. This progress type also indicates that the device has abandoned trying to bootstrap off this bootstrap server."; } enum boot-image-mismatch { description "Indicates that the device has determined that it is not running the correct boot image. This message SHOULD precipitate trying to download a boot image."; } enum boot-image-installed-rebooting { description "Indicates that the device successfully installed a new boot image and is about to reboot. After sending this progress type, the device is not expected to access the bootstrap server again for this bootstrapping attempt."; } enum boot-image-complete { description "Indicates that the device believes that it is running the correct boot image."; } enum pre-script-initiated { description "Indicates that the device is about to execute the 'pre-configuration-script'."; } enum pre-script-warning { description "Indicates that the device obtained a warning from the 'pre-configuration-script' when it was executed. The 'message' node below SHOULD capture any output the script produces."; } enum pre-script-error { description "Indicates that the device obtained an error from the 'pre-configuration-script' when it was executed. The 'message' node below SHOULD capture any output the script produces. This progress type also indicates
that the device has abandoned trying to bootstrap off this bootstrap server."; } enum pre-script-complete { description "Indicates that the device successfully executed the 'pre-configuration-script'."; } enum config-initiated { description "Indicates that the device is about to commit the initial configuration."; } enum config-warning { description "Indicates that the device obtained warning messages when it committed the initial configuration. The 'message' node below SHOULD indicate any warning messages that were generated."; } enum config-error { description "Indicates that the device obtained error messages when it committed the initial configuration. The 'message' node below SHOULD indicate the error messages that were generated. This progress type also indicates that the device has abandoned trying to bootstrap off this bootstrap server."; } enum config-complete { description "Indicates that the device successfully committed the initial configuration."; } enum post-script-initiated { description "Indicates that the device is about to execute the 'post-configuration-script'."; } enum post-script-warning { description "Indicates that the device obtained a warning from the 'post-configuration-script' when it was executed. The 'message' node below SHOULD capture any output the script produces."; } enum post-script-error { description
"Indicates that the device obtained an error from the 'post-configuration-script' when it was executed. The 'message' node below SHOULD capture any output the script produces. This progress type also indicates that the device has abandoned trying to bootstrap off this bootstrap server."; } enum post-script-complete { description "Indicates that the device successfully executed the 'post-configuration-script'."; } enum bootstrap-warning { description "Indicates that a warning condition occurred for which no other 'progress-type' enumeration is deemed suitable. The 'message' node below SHOULD describe the warning."; } enum bootstrap-error { description "Indicates that an error condition occurred for which no other 'progress-type' enumeration is deemed suitable. The 'message' node below SHOULD describe the error. This progress type also indicates that the device has abandoned trying to bootstrap off this bootstrap server."; } enum bootstrap-complete { description "Indicates that the device successfully processed all 'onboarding-information' provided and that it is ready to be managed. The 'message' node below MAY contain any additional information that the manufacturer thinks might be useful. After sending this progress type, the device is not expected to access the bootstrap server again."; } enum informational { description "Indicates any additional information not captured by any of the other progress types. For instance, a message indicating that the device is about to reboot after having installed a boot image could be provided. The 'message' node below SHOULD contain information that the manufacturer thinks might be useful."; }
} mandatory true; description "The type of progress report provided."; } leaf message { type string; description "An optional arbitrary value."; } container ssh-host-keys { when "../progress-type = 'bootstrap-complete'" { description "SSH host keys are only sent when the progress type is 'bootstrap-complete'."; } description "A list of SSH host keys an NMS may use to authenticate subsequent SSH-based connections to this device (e.g., netconf-ssh, netconf-ch-ssh)."; list ssh-host-key { description "An SSH host key an NMS may use to authenticate subsequent SSH-based connections to this device (e.g., netconf-ssh and netconf-ch-ssh)."; reference "RFC 4253: The Secure Shell (SSH) Transport Layer Protocol"; leaf algorithm { type string; mandatory true; description "The public key algorithm name for this SSH key. Valid values are listed in the 'Public Key Algorithm Names' subregistry of the 'Secure Shell (SSH) Protocol Parameters' registry maintained by IANA."; reference "RFC 4250: The Secure Shell (SSH) Protocol Assigned Numbers IANA URL: <https://www.iana.org/assignments/ssh-para\\ meters> ('\\' added for formatting reasons)"; } leaf key-data { type binary; mandatory true; description
"The binary public key data for this SSH key, as specified by RFC 4253, Section 6.6; that is: string certificate or public key format identifier byte[n] key/certificate data."; reference "RFC 4253: The Secure Shell (SSH) Transport Layer Protocol"; } } } container trust-anchor-certs { when "../progress-type = 'bootstrap-complete'" { description "Trust anchors are only sent when the progress type is 'bootstrap-complete'."; } description "A list of trust anchor certificates an NMS may use to authenticate subsequent certificate-based connections to this device (e.g., restconf-tls, netconf-tls, or even netconf-ssh with X.509 support from RFC 6187). In practice, trust anchors for IDevID certificates do not need to be conveyed using this mechanism."; reference "RFC 6187: X.509v3 Certificates for Secure Shell Authentication"; leaf-list trust-anchor-cert { type cms; description "A CMS structure whose topmost content type MUST be the signed-data content type, as described by Section 5 of RFC 5652. The CMS MUST contain the chain of X.509 certificates needed to authenticate the certificate presented by the device. The CMS MUST contain only a single chain of certificates. The last certificate in the chain MUST be the issuer for the device's end-entity certificate. In all cases, the chain MUST include a self-signed root certificate. In the case where the root certificate is itself the issuer of the device's end-entity certificate, only one certificate is
present. This CMS encodes the degenerate form of the SignedData structure that is commonly used to disseminate X.509 certificates and revocation objects (RFC 5280)."; reference "RFC 5280: Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile RFC 5652: Cryptographic Message Syntax (CMS)"; } } } } } <CODE ENDS>8. DHCP Options
This section defines two DHCP options: one for DHCPv4 and one for DHCPv6. These two options are semantically the same, though syntactically different.8.1. DHCPv4 SZTP Redirect Option
The DHCPv4 SZTP Redirect Option is used to provision the client with one or more URIs for bootstrap servers that can be contacted to attempt further configuration. 0 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | option-code (143) | option-length | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ . . . bootstrap-server-list (variable length) . . . +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ * option-code: OPTION_V4_SZTP_REDIRECT (143) * option-length: The option length in octets. * bootstrap-server-list: A list of servers for the client to attempt contacting, in order to obtain further bootstrapping data, in the format shown in Section 8.3. DHCPv4 SZTP Redirect Option
DHCPv4 Client Behavior Clients MAY request the OPTION_V4_SZTP_REDIRECT option by including its option code in the Parameter Request List (55) in DHCP request messages. On receipt of a DHCPv4 Reply message that contains the OPTION_V4_SZTP_REDIRECT option, the client processes the response according to Section 5.5, with the understanding that the "address" and "port" values are encoded in the URIs. Any invalid URI entries received in the uri-data field are ignored by the client. If the received OPTION_V4_SZTP_REDIRECT option does not contain at least one valid URI entry in the uri-data field, then the client MUST discard the option. As the list of URIs may exceed the maximum allowed length of a single DHCPv4 option (255 octets), the client MUST implement the decoding agent behavior described in [RFC3396], to correctly process a URI list split across a number of received OPTION_V4_SZTP_REDIRECT option instances. DHCPv4 Server Behavior The DHCPv4 server MAY include a single instance of the OPTION_V4_SZTP_REDIRECT option in DHCP messages it sends. Servers MUST NOT send more than one instance of the OPTION_V4_SZTP_REDIRECT option. The server's DHCP message MUST contain only a single instance of the OPTION_V4_SZTP_REDIRECT's 'bootstrap-server-list' field. However, the list of URIs in this field may exceed the maximum allowed length of a single DHCPv4 option (per [RFC3396]). If the length of 'bootstrap-server-list' is small enough to fit into a single instance of OPTION_V4_SZTP_REDIRECT, the server MUST NOT send more than one instance of this option. If the length of the 'bootstrap-server-list' field is too large to fit into a single option, then OPTION_V4_SZTP_REDIRECT MUST be split into multiple instances of the option according to the process described in [RFC3396].
8.2. DHCPv6 SZTP Redirect Option
The DHCPv6 SZTP Redirect Option is used to provision the client with one or more URIs for bootstrap servers that can be contacted to attempt further configuration. 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | option-code (136) | option-length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ . bootstrap-server-list (variable length) . +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * option-code: OPTION_V6_SZTP_REDIRECT (136) * option-length: The option length in octets. * bootstrap-server-list: A list of servers for the client to attempt contacting, in order to obtain further bootstrapping data, in the format shown in Section 8.3. DHCPv6 SZTP Redirect Option DHCPv6 Client Behavior Clients MAY request OPTION_V6_SZTP_REDIRECT using the process defined in [RFC8415], Sections 18.2.1, 18.2.2, 18.2.4, 18.2.5, 18.2.6, and 21.7. As a convenience to the reader, we mention here that the client includes requested option codes in the Option Request option. On receipt of a DHCPv6 Reply message that contains the OPTION_V6_SZTP_REDIRECT option, the client processes the response according to Section 5.5, with the understanding that the "address" and "port" values are encoded in the URIs. Any invalid URI entries received in the uri-data field are ignored by the client. If the received OPTION_V6_SZTP_REDIRECT option does not contain at least one valid URI entry in the uri-data field, then the client MUST discard the option. DHCPv6 Server Behavior Section 18.3 of [RFC8415] governs server operation in regard to option assignment. As a convenience to the reader, we mention here that the server will send a particular option code only if configured with specific values for that option code and if the client requested it.
The OPTION_V6_SZTP_REDIRECT option is a singleton. Servers MUST NOT send more than one instance of this option.8.3. Common Field Encoding
Both of the DHCPv4 and DHCPv6 options defined in this section encode a list of bootstrap server URIs. The "URI" structure is a DHCP option that can contain multiple URIs (see [RFC7227], Section 5.7). Each URI entry in the bootstrap-server-list is structured as follows: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-...-+-+-+-+-+-+-+ | uri-length | URI | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-...-+-+-+-+-+-+-+ * uri-length: 2 octets long; specifies the length of the URI data. * URI: URI of the SZTP bootstrap server. The URI of the SZTP bootstrap server MUST use the "https" URI scheme defined in Section 2.7.2 of [RFC7230], and it MUST be in form "https://<ip-address-or-hostname>[:<port>]".