Subject: Re: [Netconf] zerotouch/19: How to encode YANG-modeled artifacts?

From: Kent Watsen <[email-masked]>
Date: Sat, 25 Feb 2017 04:52:26 +0000

[picking up on this thread]

I've updated the YANG to use rc:yang-data for the artifact definition, but
now I'm wondering about the best way to define the RESTCONF API.

To be clear, what I did to the YANG was to move the schema for the 
'information-type' subtree (see below) to a grouping, and then used
that grouping both by the rc:yang-data definition as well as in the
API.  Doing this enables the API to stay the same as it is currently:

0. module: ietf-zerotouch
    +--ro device* [unique-id]
       +--ro unique-id                 string
       +--ro (information-type)
       |  +--:(redirect-information)
       |  |  +--ro redirect-information
       |  |     +--ro bootstrap-server* [address]
       |  |        +--ro address         inet:host
       |  |        +--ro port?           inet:port-number
       |  |        +--ro trust-anchor?   binary
       |  +--:(bootstrap-information)
       |     +--ro bootstrap-information
       |        +--ro boot-image
       |        |  +--ro name      string
       |        |  +--ro (hash-algorithm)
       |        |  |  +--:(sha256)
       |        |  |     +--ro sha256?   string
       |        |  +--ro uri*      inet:uri
       |        +--ro configuration-handling?      enumeration
       |        +--ro pre-configuration-script?    script
       |        +--ro configuration?
       |        +--ro post-configuration-script?   script
       +--ro signature?                binary
       +--ro ownership-voucher?        binary
       +--ro owner-certificate?        binary
       +--ro voucher-revocation?       binary
       +--ro certificate-revocation?   binary

However, I think that it would be better if we changed the API to return
the 'artifact' as a binary object.  That way it's just the API returning
the artifact, as opposed to the API returning the same data as the artifact.

However, to do this, we'd have to address the artifact's encoding (xml or
json), to which I'd recommend hardcoding JSON, to match how the ANIMA team 
chose JSON for the voucher artifact's encoding.  [Note: picking an encoding
for the artifact has no impact on if the RESTCONF API returns XML of JSON,
it only affects what is encoded inside the binary artifact.]  If we made 
this change, the API would look like this:

1. module: ietf-zerotouch
    +--ro device* [unique-id]
      +--ro unique-id                 string
      +--ro information-type          binary  // base64-encoded json
      +--ro signature?                binary  // pkcs#7 structure
      +--ro ownership-voucher?        binary  // pkcs#7 structure
      +--ro owner-certificate?        binary  // pkcs#7 structure
      +--ro voucher-revocation?       binary  // pkcs#7 structure
      +--ro certificate-revocation?   binary  // pkcs#7 structure

But, an even better solution would be to 1) wrap the JSON inside a
PKCS#7 structure that 2) can have an *optional* signature.  Doing this
would result in the following API:

2. module: ietf-zerotouch
    +--ro device* [unique-id]
      +--ro unique-id                 string
      +--ro information-type          binary  // pkcs#7 (+ opt signature)
      +--ro ownership-voucher?        binary  // pkcs#7 
      +--ro owner-certificate?        binary  // pkcs#7 
      +--ro voucher-revocation?       binary  // pkcs#7 
      +--ro certificate-revocation?   binary  // pkcs#7 

If we wanted to be even more aggressive, we could try merging the following
artifacts together:
a. owner-certificate + optional cert-revocation --> owner-certificate'
b. ownership-voucher + optional voucher-revocation --> ownership-voucher'

Warning: (b) may only be possible depending on if the ANIMA WG changes
the voucher and voucher-revocation formats to use X.509v3 extensions.

This option groups everything into logical clumps, which is conceptually 
very nice and should be easier to work with (less number of moving parts).  
However, it would be more effort for the NMSs to generate these combo 
files.  Actually, I'm less worried about the increased effort than the fact
it's merging long-lived info with short-lived info.  I.e. the vendor might
generate an owner certificate that never expires, but issues new revocation
information weekly.  It's fine from a processing perspective, but the 
"owner-certificate" presented by the API would no longer be exactly the
same as provided by the vendor, so simple command-line `diff` operations
wouldn't be possible.  This option would result in this very clean looking
API:

3. module: ietf-zerotouch
    +--ro device* [unique-id]
      +--ro unique-id                 string
      +--ro information-type          binary  // pkcs#7 (+ opt signature)
      +--ro ownership-voucher?        binary  // pkcs#7 (+ opt revocations)
      +--ro owner-certificate?        binary  // pkcs#7 (+ opt revocations)

To recap, here are the options:

0: keep as is
1: return JSON (as a binary type)
2: return JSON inside an optionally signed PKCS#7 structure
3: #2 plus also fold the revocations into the associated pkcs7 file

My preference is #3, because it's the cleanest solution.  FWIW, I have
a  meeting with the ANIMA group on this coming Tuesday, during which 
I'll make a case for doing what's necessary to support #3.

Otherwise, does anyone have any comments on any of this?

Thanks,
Kent