https://redmine.named-data.net/https://redmine.named-data.net/favicon.ico?14759811232015-04-23T10:25:29ZNDN project issue tracking systemndn-cxx - Feature #2766: CertificateBundle: designhttps://redmine.named-data.net/issues/2766?journal_id=96952015-04-23T10:25:29ZYingdi Yuyuyingdi@gmail.com
<ul><li><strong>Related to</strong> <i><a class="issue tracker-2 status-5 priority-2 priority-default closed" href="/issues/2451">Feature #2451</a>: New Abstraction for Identity Key Certificate</i> added</li></ul> ndn-cxx - Feature #2766: CertificateBundle: designhttps://redmine.named-data.net/issues/2766?journal_id=96962015-04-23T10:26:03ZJunxiao Shi
<ul><li><strong>Tracker</strong> changed from <i>Task</i> to <i>Feature</i></li><li><strong>Subject</strong> changed from <i>Support key-bundle support in PIB</i> to <i>Support key-bundle in PIB</i></li><li><strong>Start date</strong> deleted (<del><i>04/23/2015</i></del>)</li></ul> ndn-cxx - Feature #2766: CertificateBundle: designhttps://redmine.named-data.net/issues/2766?journal_id=178432016-12-14T12:41:31ZAlex Afanasyev
<ul><li><strong>Subject</strong> changed from <i>Support key-bundle in PIB</i> to <i>KeyBundle: design</i></li><li><strong>Description</strong> updated (<a title="View differences" href="/journals/17843/diff?detail_id=15641">diff</a>)</li></ul> ndn-cxx - Feature #2766: CertificateBundle: designhttps://redmine.named-data.net/issues/2766?journal_id=178442016-12-14T12:42:02ZAlex Afanasyev
<ul></ul><p>Preliminary design description: <a href="https://docs.google.com/document/d/1eMwwIUu4DMmL4UxbuKSsZAeWkOpOM6cBygzBNH5IYcA/edit?usp=sharing">https://docs.google.com/document/d/1eMwwIUu4DMmL4UxbuKSsZAeWkOpOM6cBygzBNH5IYcA/edit?usp=sharing</a></p>
ndn-cxx - Feature #2766: CertificateBundle: designhttps://redmine.named-data.net/issues/2766?journal_id=178462016-12-14T12:42:11ZAlex Afanasyev
<ul><li><strong>Related to</strong> deleted (<i><a class="issue tracker-2 status-5 priority-2 priority-default closed" href="/issues/2451">Feature #2451</a>: New Abstraction for Identity Key Certificate</i>)</li></ul> ndn-cxx - Feature #2766: CertificateBundle: designhttps://redmine.named-data.net/issues/2766?journal_id=178472016-12-14T12:49:23ZAlex Afanasyev
<ul><li><strong>Blocks</strong> <i><a class="issue tracker-2 status-5 priority-2 priority-default closed" href="/issues/3891">Feature #3891</a>: Integrate fetching certificates using KeyBundle into the Validator</i> added</li></ul> ndn-cxx - Feature #2766: CertificateBundle: designhttps://redmine.named-data.net/issues/2766?journal_id=178492016-12-14T12:50:10ZAlex Afanasyev
<ul><li><strong>Blocks</strong> <i><a class="issue tracker-2 status-9 priority-2 priority-default closed" href="/issues/3892">Feature #3892</a>: Integrate publishing of KeyBundle into Face::setInterestFilter</i> added</li></ul> ndn-cxx - Feature #2766: CertificateBundle: designhttps://redmine.named-data.net/issues/2766?journal_id=178542016-12-14T12:58:20ZAlex Afanasyev
<ul><li><strong>Assignee</strong> set to <i>Manika Mittal</i></li><li><strong>Target version</strong> set to <i>v0.6</i></li></ul> ndn-cxx - Feature #2766: CertificateBundle: designhttps://redmine.named-data.net/issues/2766?journal_id=181122017-01-12T20:59:29ZAlex Afanasyev
<ul><li><strong>Status</strong> changed from <i>New</i> to <i>Feedback</i></li><li><strong>% Done</strong> changed from <i>0</i> to <i>80</i></li></ul> ndn-cxx - Feature #2766: CertificateBundle: designhttps://redmine.named-data.net/issues/2766?journal_id=182042017-01-25T12:44:49ZJunxiao Shi
<ul></ul><p>Where's the spec? If it's already on Gerrit, post the link here.</p>
ndn-cxx - Feature #2766: CertificateBundle: designhttps://redmine.named-data.net/issues/2766?journal_id=182062017-01-25T12:53:18ZAlex Afanasyev
<ul></ul><p>See the link in note 4</p>
ndn-cxx - Feature #2766: CertificateBundle: designhttps://redmine.named-data.net/issues/2766?journal_id=182082017-01-25T13:06:10ZManika Mittal
<ul></ul><p>I will update the specs to reflect the new validator interface. </p>
ndn-cxx - Feature #2766: CertificateBundle: designhttps://redmine.named-data.net/issues/2766?journal_id=182352017-01-28T12:39:35ZJunxiao Shi
<ul></ul><p>I've briefly read the spec.</p>
<p>It's unclear how "list of certificates" is encoded. This needs to be formally declared.</p>
<p>Must the KeyBundle contain a complete certificate chain? Are certificates required to appear in a certain order?</p>
<p>How does a Validator know whether the requester has prepared a KeyBundle or it should retrieve individual certificates instead?</p>
<p>Why does the KeyBundle carry the trust anchor certificate? Trust anchor is already known by the validator and should be omitted. In WebPKI, the web server does not send root CA certificate in its certificate chain.</p>
ndn-cxx - Feature #2766: CertificateBundle: designhttps://redmine.named-data.net/issues/2766?journal_id=182862017-02-06T11:37:23ZManika Mittal
<ul></ul><p>I will add the packet spec on wiki here. I have updated the consumer side spec on the google doc. </p>
<p>The Bundle is expected to have the certificates in a certain order i.e. from the first certificate needed to validate the data packet itself, followed by the certificate needed to validate the first certificate, so on and so forth. </p>
<p>The validator first requests for a Certificate Bundle and if that interest times out or returns a Nack it will fetch individual certificates from the network. </p>
<p>Whether the bundle carries the trust anchor or not is undefined. The producer will create the bundle as per it's knowledge i.e. till it either reaches a self signed certificate or may be a loop or may be some const MAX_BUNDLE_SIZE. </p>
ndn-cxx - Feature #2766: CertificateBundle: designhttps://redmine.named-data.net/issues/2766?journal_id=182872017-02-06T13:56:49ZManika Mittal
<ul></ul><p>Packet format specs : <a href="https://redmine.named-data.net/projects/ndn-cxx/wiki/Certificate_Bundle_Packet_Format">https://redmine.named-data.net/projects/ndn-cxx/wiki/Certificate_Bundle_Packet_Format</a> </p>
ndn-cxx - Feature #2766: CertificateBundle: designhttps://redmine.named-data.net/issues/2766?journal_id=182962017-02-06T15:23:41ZMuktadir Chowdhurymrchwdhr@memphis.edu
<ul><li><strong>Related to</strong> <i><a class="issue tracker-3 status-1 priority-2 priority-default" href="/issues/3950">Task #3950</a>: Use CertificateBundleFetcher instead of DirectFetcher</i> added</li></ul> ndn-cxx - Feature #2766: CertificateBundle: designhttps://redmine.named-data.net/issues/2766?journal_id=183062017-02-07T21:52:45ZJunxiao Shi
<ul></ul><blockquote>
<p>The Bundle is expected to have the certificates in a certain order i.e. from the first certificate needed to validate the data packet itself, followed by the certificate needed to validate the first certificate, so on and so forth. </p>
</blockquote>
<p>This implies that a prover must have access to the trust schema in order to generate a bundle, because the trust schema defines which certificates are needed to verify a packet and in what order. This is a reasonable assumption.<br>
A consequence is that the name of a bundle should indicate which trust schema is in use, because the same certificate may potentially be used by multiple applications with different trust schemas. <a class="wiki-page" href="https://redmine.named-data.net/projects/ndn-cxx/wiki/Certificate_Bundle_Packet_Format">Certificate_Bundle_Packet_Format</a> rev1 includes <code><trust-model></code> component in a bundle name, but lacks an explanation on how the verifier can derive this name from the certificate name which is the only information available in KeyLocator.</p>
<blockquote>
<p>Whether the bundle carries the trust anchor or not is undefined.</p>
</blockquote>
<p>This needs more explanation in the documents, because it's unobvious for a reader who knows PKI fairly well, as WebPKI recommends not to include the trust anchor (root CA certificate) in the certificate chain sent by a TLS sever.<br>
I do see a valid use case for including the trust anchor (even if it's self-signed) in the bundle: the verifier's trust schema may only contain a digest of the trust anchor certificate instead of the full certificate. In this case, including the trust anchor would allow the verifier to see the public key.</p>
<blockquote>
<p>The producer will create the bundle as per it's knowledge i.e. till it either reaches a self signed certificate or may be a loop or may be some const MAX_BUNDLE_SIZE.</p>
</blockquote>
<p>If the verifier encounters an incomplete bundle, i.e. it needs more certificates than what's available from the bundle, does the verifier attempt to retrieval additional certificates individually?</p>
<blockquote>
<p>the certificates present in the bundle are cached in the unverified cache and the validation process continues on the first certificate present in the bundle. Note it is assumed that the certificate bundle has its certificates is in a certain order where the first certificate is the certificate needed to validate the signature of the target data packet.</p>
</blockquote>
<p>If the certificate bundle only serves as a data source to populate the unverified certificate cache, what's the purpose of the recommendation that certificates are sorted in a certain order?</p>
<blockquote>
<p>there is a version number because it’s possible that the Certificate Bundle is updated (in case some key in the chain is revoked)</p>
</blockquote>
<p>How to ensure the verifier is retrieving the latest version, or at least a good enough version that does not contain a revoked/expired intermediate certificate, instead of an older version from a network cache that eventually causes the verificate to fail?</p>
<blockquote>
<p>Each segment will always have complete certificates.</p>
</blockquote>
<p>What's the benefit of this requirement?<br>
The obvious drawback is not being able to use the full size of a Data packet, and impossible to encapsulate the certificate that is close to the size limit because the outer name needs extra bytes.<br>
Note that "if the first segment contains enough certificates then we don't retrieve the second segment" is not a valid reason for requiring segment to stop at certificate boundary, because the stream constructed by contents from segments can be processed in the same way as NFD <code>UnixStreamTransport</code> reads LpPackets from a stream socket.</p>
ndn-cxx - Feature #2766: CertificateBundle: designhttps://redmine.named-data.net/issues/2766?journal_id=183152017-02-08T14:07:24ZManika Mittal
<ul></ul><blockquote>
<p>A consequence is that the name of a bundle should indicate which trust schema is in use, because the same certificate may potentially be used by multiple applications with different trust schemas. Certificate_Bundle_Packet_Format rev1 includes <code><trust-model></code> component in a bundle name, but lacks an explanation on how the verifier can derive this name from the certificate name which is the only information available in KeyLocator.</p>
</blockquote>
<p>For now we only support the trust models with a single hierarchy. I will append a number "00" as a component in the Bundle name to represent that and add that in the specs too. </p>
<blockquote>
<p>This needs more explanation in the documents, because it's unobvious for a reader who knows PKI fairly well, as WebPKI recommends not to include the trust anchor (root CA certificate) in the certificate chain sent by a TLS server.</p>
</blockquote>
<p>I will add more explanation. Basically, if the trust anchor is agreed upon by both the producer and the consumer then we don't have to include it. But currently we don't know this. It's possible that a trust model as no fixed trust anchor. So it's undefined. </p>
<blockquote>
<p>If the verifier encounters an incomplete bundle, i.e. it needs more certificates than what's available from the bundle, does the verifier attempt to retrieval additional certificates individually?</p>
</blockquote>
<p>Yes. </p>
<blockquote>
<p>If the certificate bundle only serves as a data source to populate the unverified certificate cache, what's the purpose of the recommendation that certificates are sorted in a certain order?</p>
</blockquote>
<p>I would say it's better to keep it sorted because we don't want to fetch all the segments if we don't have to. So if the certificates are in random order in the bundle it might lead to some additional fetches which could have been avoided if the certificates were in order. </p>
<blockquote>
<p>How to ensure the verifier is retrieving the latest version, or at least a good enough version that does not contain a revoked/expired intermediate certificate, instead of an older version from a network cache that eventually causes the verification to fail?</p>
</blockquote>
<p>Currently, we only rely on freshness period and must be fresh. </p>
<blockquote>
<p>What's the benefit of this requirement?</p>
</blockquote>
<p>Actually, this is not a hard requirement. May be I can mention that in the spec that it is mostly for simplicity. </p>
ndn-cxx - Feature #2766: CertificateBundle: designhttps://redmine.named-data.net/issues/2766?journal_id=183172017-02-08T14:41:38ZJunxiao Shi
<ul></ul><blockquote>
<p>For now we only support the trust models with a single hierarchy. I will append a number "00" as a component in the Bundle name to represent that and add that in the specs too. </p>
</blockquote>
<p>Are you saying that each data-signing-certificate is usable with one trust schema? This is too much restriction and is unacceptable.</p>
<blockquote>
<p>It's possible that a trust model as no fixed trust anchor.</p>
</blockquote>
<p>WebPKI has many root CAs, but the issuer of the highest level of intermediate CA is the trust anchor being used. Similarly, an NDN trust schema can have multiple trust anchors, and the bundle only needs to include up to the certificate directly issued by one of the trust anchors, but not the self-signed trust anchor. An exception is the verifier does not have the public key of the trust anchor, as described in note-17.</p>
<blockquote>
<blockquote>
<p>If the certificate bundle only serves as a data source to populate the unverified certificate cache, what's the purpose of the recommendation that certificates are sorted in a certain order?</p>
</blockquote>
<p>I would say it's better to keep it sorted because we don't want to fetch all the segments if we don't have to. So if the certificates are in random order in the bundle it might lead to some additional fetches which could have been avoided if the certificates were in order. </p>
</blockquote>
<p>Agreed. This should be a SHOULD-level requirement rather than a MUST-level, and the rationale needs to explained in the document.</p>
<blockquote>
<blockquote>
<p>How to ensure the verifier is retrieving the latest version, or at least a good enough version that does not contain a revoked/expired intermediate certificate, instead of an older version from a network cache that eventually causes the verification to fail?</p>
</blockquote>
<p>Currently, we only rely on freshness period and must be fresh. </p>
</blockquote>
<p>As you know, these are mostly useless. This should appear as a known limitation in the documents.</p>
<blockquote>
<blockquote>
<blockquote>
<p>Each segment will always have complete certificates.<br>
What's the benefit of this requirement?</p>
</blockquote>
</blockquote>
<p>Actually, this is not a hard requirement. May be I can mention that in the spec that it is mostly for simplicity.</p>
</blockquote>
<p>Are you saying this is a MAY-level requirement? If so, verifier needs to be able to accept a bundle in which segment does not stop at certificate boundary, since a MAY-level requirement is truly optional at prover end.</p>
ndn-cxx - Feature #2766: CertificateBundle: designhttps://redmine.named-data.net/issues/2766?journal_id=183182017-02-08T14:54:36ZAlex Afanasyev
<ul></ul><p>Junxiao Shi wrote:</p>
<blockquote>
<blockquote>
<p>For now we only support the trust models with a single hierarchy. I will append a number "00" as a component in the Bundle name to represent that and add that in the specs too. </p>
</blockquote>
<p>Are you saying that each data-signing-certificate is usable with one trust schema? This is too much restriction and is unacceptable.</p>
</blockquote>
<p>I don't understand this comment. What Manika mentioned is that the current bundle can help with certificate retrieval for any trust schema that uses a single chain of certificates to verify a data packet (this is what single hierarchy is meant, it is not related in any way to name hierarchy or any restrictions on data/cert names). In principle, bundle can help Web-of-Trust models, but this will be defined/implemented, probably specific to an applications.</p>
<blockquote>
<blockquote>
<p>It's possible that a trust model as no fixed trust anchor.</p>
</blockquote>
<p>WebPKI has many root CAs, but the issuer of the highest level of intermediate CA is the trust anchor being used. Similarly, an NDN trust schema can have multiple trust anchors, and the bundle only needs to include up to the certificate directly issued by one of the trust anchors, but not the self-signed trust anchor. An exception is the verifier does not have the public key of the trust anchor, as described in note-17.</p>
</blockquote>
<p>Bundle doesn't by itself impose trust model. It is just a combined set of certificates. It doesn't have knowledge of specific trust anchors, so whatever is included is included. Ultimately, it is Validator task to get proper certificates. Carrying them in a bundle is just a helper.</p>
<blockquote>
<blockquote>
<blockquote>
<blockquote>
<p>Each segment will always have complete certificates.<br>
What's the benefit of this requirement?</p>
</blockquote>
</blockquote>
<p>Actually, this is not a hard requirement. May be I can mention that in the spec that it is mostly for simplicity.</p>
</blockquote>
<p>Are you saying this is a MAY-level requirement? If so, verifier needs to be able to accept a bundle in which segment does not stop at certificate boundary, since a MAY-level requirement is truly optional at prover end.</p>
</blockquote>
<p>As of now, it is MUST-level requirement. The goal for now to make implementation simple. This may change in the future and we may change the validator implementation, but I do not want to overcomplicate things for now.</p>
ndn-cxx - Feature #2766: CertificateBundle: designhttps://redmine.named-data.net/issues/2766?journal_id=183192017-02-08T15:42:48ZJunxiao Shi
<ul></ul><blockquote>
<p>the current bundle can help with certificate retrieval for any trust schema that uses a single chain of certificates to verify a data packet</p>
</blockquote>
<p>An <a href="https://letsencrypt.org/certificates/" class="external">example in WebPKI</a>: <em>Let’s Encrypt Authority X3</em> intermediate is issued by <em>ISRG Root X1</em> and cross-signed by <em>IdenTrust</em> root. Before <em>ISRG Root X1</em> is trusted by browsers, certificate chains will look like "example.com - <em>Let’s Encrypt Authority X3 (issuer=IdenTrust)</em>". After <em>ISRG Root X1</em> becomes trusted by browsers, certificate chains will look like "example.com - <em>Let’s Encrypt Authority X3 (issuer=ISRG)</em>". Note that <em>Let’s Encrypt Authority X3 (issuer=IdenTrust)</em> and <em>Let’s Encrypt Authority X3 (issuer=ISRG)</em> are two different certificates but they contain same public key.</p>
<p>Bringing this example to NDN trust schema: seeing example.com's certificate, the trust schema installed in Firefox 49 or below will derive <em>Let’s Encrypt Authority X3 (issuer=IdenTrust)</em> as the issuer, while the trust schema installed in Firefox 50 or above will derive <em>Let’s Encrypt Authority X3 (issuer=ISRG)</em> as the issuer.<br>
How does the TLS server which intermediate should be sent in the bundle, if the bundle name does not contain an indicate on which trust schema is in use?</p>
<p>On the other hand, if we eliminate the requirement of sorting the certificates, this problem can be solved by including both <em>Let’s Encrypt Authority X3 (issuer=IdenTrust)</em> and <em>Let’s Encrypt Authority X3 (issuer=ISRG)</em> in the bundle, and verifier will take what they need from the unverified cache.</p>
<blockquote>
<p>bundle can help Web-of-Trust models, but this will be defined/implemented, probably specific to an applications.</p>
</blockquote>
<p>In Web-of-Trust, there are multiple issuers for one certificate and all those issuers' certificates must be retrieved and verified. I don't think NDN trust schema can support such model, and thus it's not a problem specific to bundle.</p>
<blockquote>
<p>Bundle doesn't by itself impose trust model. It is just a combined set of certificates. It doesn't have knowledge of specific trust anchors, so whatever is included is included.</p>
</blockquote>
<p>What would be the benefit of including a <em>self-signed certificate</em> (regardless of whether it is a trust anchor)? other than the situation in note-17.</p>
<blockquote>
<p>As of now, it is MUST-level requirement. The goal for now to make implementation simple. This may change in the future and we may change the validator implementation, but I do not want to overcomplicate things for now.</p>
</blockquote>
<p>As indicated in note-17, there is an obvious drawback, and the so-called simplification is invalid because exactly same procedure is already implemented in <code>UnixStreamTransport</code> and can be abstracted into a reusable library routine.<br>
A real simplification is: just use <code>SegmentFetcher</code> and retrieve all segments, and leave "stop retrieving after getting enough segments" for later optimization.</p>
ndn-cxx - Feature #2766: CertificateBundle: designhttps://redmine.named-data.net/issues/2766?journal_id=183202017-02-08T16:02:31ZAlex Afanasyev
<ul></ul><p>Junxiao Shi wrote:</p>
<blockquote>
<blockquote>
<p>the current bundle can help with certificate retrieval for any trust schema that uses a single chain of certificates to verify a data packet</p>
</blockquote>
<p>An <a href="https://letsencrypt.org/certificates/" class="external">example in WebPKI</a>: <em>Let’s Encrypt Authority X3</em> intermediate is issued by <em>ISRG Root X1</em> and cross-signed by <em>IdenTrust</em> root. Before <em>ISRG Root X1</em> is trusted by browsers, certificate chains will look like "example.com - <em>Let’s Encrypt Authority X3 (issuer=IdenTrust)</em>". After <em>ISRG Root X1</em> becomes trusted by browsers, certificate chains will look like "example.com - <em>Let’s Encrypt Authority X3 (issuer=ISRG)</em>". Note that <em>Let’s Encrypt Authority X3 (issuer=IdenTrust)</em> and <em>Let’s Encrypt Authority X3 (issuer=ISRG)</em> are two different certificates but they contain same public key.</p>
<p>Bringing this example to NDN trust schema: seeing example.com's certificate, the trust schema installed in Firefox 49 or below will derive <em>Let’s Encrypt Authority X3 (issuer=IdenTrust)</em> as the issuer, while the trust schema installed in Firefox 50 or above will derive <em>Let’s Encrypt Authority X3 (issuer=ISRG)</em> as the issuer.<br>
How does the TLS server which intermediate should be sent in the bundle, if the bundle name does not contain an indicate on which trust schema is in use?</p>
<p>On the other hand, if we eliminate the requirement of sorting the certificates, this problem can be solved by including both <em>Let’s Encrypt Authority X3 (issuer=IdenTrust)</em> and <em>Let’s Encrypt Authority X3 (issuer=ISRG)</em> in the bundle, and verifier will take what they need from the unverified cache.</p>
</blockquote>
<p>Why you bringing TLS here? You just effectively described a form of web-of-trust (multi-cert) model. This is not supported in our initial implementation of bundle fetcher nor bundle helper, but is irrelevant from the spec point of view. Bundle includes all certificates potentially needed, some may not be actually used. If use case of cert bundle will get to the point of specific trust model with specific trust anchors, then one free to construct a non-redundant bundle, but I don't know exactly where you going with it.</p>
<blockquote>
<blockquote>
<p>bundle can help Web-of-Trust models, but this will be defined/implemented, probably specific to an applications.</p>
</blockquote>
<p>In Web-of-Trust, there are multiple issuers for one certificate and all those issuers' certificates must be retrieved and verified. I don't think NDN trust schema can support such model, and thus it's not a problem specific to bundle.</p>
</blockquote>
<p>Trust schema can support anything. You're referring a challenge in certificate retrieval (signature discovery). This is totally different question and outside the scope for both current schema and cert bundle specs. We have been discussing a few proposals about this and there was one implementation (in ChronoChat) for that, but nothing is definitive yet.</p>
<blockquote>
<blockquote>
<p>Bundle doesn't by itself impose trust model. It is just a combined set of certificates. It doesn't have knowledge of specific trust anchors, so whatever is included is included.</p>
</blockquote>
<p>What would be the benefit of including a <em>self-signed certificate</em> (regardless of whether it is a trust anchor)? other than the situation in note-17.</p>
</blockquote>
<p>Ok. This is a different conversation. Self-signed cert != trust anchor both ways. Self-signed cert can be a trust anchor or not be a trust anchor. And trust anchor can be self-signed or can be a non-self signed.</p>
<p>To answer your latest questions. Yes, I don't immediately see a value of including self-signed cert regardless its role in trust schema.</p>
<blockquote>
<blockquote>
<p>As of now, it is MUST-level requirement. The goal for now to make implementation simple. This may change in the future and we may change the validator implementation, but I do not want to overcomplicate things for now.</p>
</blockquote>
<p>As indicated in note-17, there is an obvious drawback, and the so-called simplification is invalid because exactly same procedure is already implemented in <code>UnixStreamTransport</code> and can be abstracted into a reusable library routine.<br>
A real simplification is: just use <code>SegmentFetcher</code> and retrieve all segments, and leave "stop retrieving after getting enough segments" for later optimization.</p>
</blockquote>
<p>No. The point is to fetch only certs (bundle parts) that are actually needed. For first data packet under namespace, this could be all segments of the bundle, for others (in sub-branches), only one or two may be needed. That's the whole idea of not using the <code>SegmentFetcher</code>.</p>
ndn-cxx - Feature #2766: CertificateBundle: designhttps://redmine.named-data.net/issues/2766?journal_id=183212017-02-08T18:28:29ZJunxiao Shi
<ul></ul><blockquote>
<p>You just effectively described a form of web-of-trust (multi-cert) model. This is not supported in our initial implementation of bundle fetcher nor bundle helper</p>
</blockquote>
<p>Isn't it already supported, since the prover can put into the bundle more certificates than needed by trust schema?</p>
<blockquote>
<p>No. The point is to fetch only certs (bundle parts) that are actually needed. For first data packet under namespace, this could be all segments of the bundle, for others (in sub-branches), only one or two may be needed. That's the whole idea of not using the <code>SegmentFetcher</code>.</p>
</blockquote>
<p>Yes, I figured that, but this is an optimization, not a requirement.<br>
On the other hand, being able to include a certificate whose size is very close to Data packet size limit is a requirement for correct protocol operation.</p>
ndn-cxx - Feature #2766: CertificateBundle: designhttps://redmine.named-data.net/issues/2766?journal_id=183222017-02-08T18:30:20ZAlex Afanasyev
<ul></ul><p>Junxiao Shi wrote:</p>
<blockquote>
<blockquote>
<p>You just effectively described a form of web-of-trust (multi-cert) model. This is not supported in our initial implementation of bundle fetcher nor bundle helper</p>
</blockquote>
<p>Isn't it already supported, since the prover can put into the bundle more certificates than needed by trust schema?</p>
</blockquote>
<p>Technically yes, it is just not a current focus. That's why I said not supported.</p>
ndn-cxx - Feature #2766: CertificateBundle: designhttps://redmine.named-data.net/issues/2766?journal_id=216342018-01-02T13:19:59ZNicholas Gordonnmgordon@memphis.edu
<ul><li><strong>Related to</strong> deleted (<i><a class="issue tracker-3 status-1 priority-2 priority-default" href="/issues/3950">Task #3950</a>: Use CertificateBundleFetcher instead of DirectFetcher</i>)</li></ul> ndn-cxx - Feature #2766: CertificateBundle: designhttps://redmine.named-data.net/issues/2766?journal_id=216352018-01-02T13:20:00ZNicholas Gordonnmgordon@memphis.edu
<ul><li><strong>Blocks</strong> <i><a class="issue tracker-3 status-1 priority-2 priority-default" href="/issues/3950">Task #3950</a>: Use CertificateBundleFetcher instead of DirectFetcher</i> added</li></ul> ndn-cxx - Feature #2766: CertificateBundle: designhttps://redmine.named-data.net/issues/2766?journal_id=221452018-02-03T20:58:01ZDavide Pesavento
<ul><li><strong>Target version</strong> changed from <i>v0.6</i> to <i>v0.7</i></li></ul> ndn-cxx - Feature #2766: CertificateBundle: designhttps://redmine.named-data.net/issues/2766?journal_id=230332018-04-16T20:44:41ZDavide Pesavento
<ul><li><strong>Blocks</strong> deleted (<i><a class="issue tracker-2 status-5 priority-2 priority-default closed" href="/issues/3891">Feature #3891</a>: Integrate fetching certificates using KeyBundle into the Validator</i>)</li></ul> ndn-cxx - Feature #2766: CertificateBundle: designhttps://redmine.named-data.net/issues/2766?journal_id=251032019-03-25T14:53:30ZJunxiao Shi
<ul><li><strong>Subject</strong> changed from <i>KeyBundle: design</i> to <i>CertificateBundle: design</i></li><li><strong>Status</strong> changed from <i>Feedback</i> to <i>In Progress</i></li><li><strong>Assignee</strong> changed from <i>Manika Mittal</i> to <i>Junxiao Shi</i></li><li><strong>% Done</strong> changed from <i>80</i> to <i>0</i></li><li><strong>Estimated time</strong> set to <i>9.00 h</i></li></ul><p>Junxiao agreed on 20190325 call to write a spec of the certificate bundle.<br>
We agreed that the "single RTT" goal of <a class="wiki-page" href="https://redmine.named-data.net/projects/ndn-cxx/wiki/Certificate_Bundle_Packet_Format">Certificate Bundle Packet Format</a> is not always necessary, and initial implementation can derive bundle name from certificate name instead of Data packet name.</p>
ndn-cxx - Feature #2766: CertificateBundle: designhttps://redmine.named-data.net/issues/2766?journal_id=251582019-04-02T19:18:39ZJunxiao Shi
<ul><li><strong>Status</strong> changed from <i>In Progress</i> to <i>Feedback</i></li><li><strong>% Done</strong> changed from <i>0</i> to <i>60</i></li></ul><a name="Certificate-Bundle-design"></a>
<h1 >Certificate Bundle design<a href="#Certificate-Bundle-design" class="wiki-anchor">¶</a></h1>
<p>A certificate bundle collects multiple certificates necessary to validate a packet into a single segmented object.<br>
When a publisher prepares a certificate bundle, it enables more efficient validation because the validator can retrieve the entire certificate chain in parallel.<br>
Without a certificate bundle, the validator would have to wait until each certificate to arrive before knowing the name of its issuer, causing more round trips.</p>
<a name="Packet-Format"></a>
<h2 >Packet Format<a href="#Packet-Format" class="wiki-anchor">¶</a></h2>
<p>A certificate bundle is a segmented object that contains certificates.</p>
<p>For each Data packet:</p>
<ul>
<li>Name MUST contain <code>32=cert-bundle</code> component.</li>
<li>Name MUST end with a segment number.</li>
<li>ContentType MUST be omitted.</li>
<li>There is no signing requirement.</li>
<li>FinalBlockId MUST be present in the last segment.</li>
</ul>
<p>The payload of the segmented object is a sequence of <a href="https://named-data.net/doc/ndn-cxx/current/specs/certificate-format.html" class="external"><code>CertificateV2</code> elements</a>.<br>
A certificate MAY span across multiple Data packets.</p>
<p>The certificates SHOULD be sorted in reverse order of the hierarchy: suppose <em>cert-A</em> is the issuer of <em>cert-B</em>, <em>cert-A</em> SHOULD come after <em>cert-B</em>.<br>
This enables the validator to abort bundle retrieval as soon as it has received enough certificates in the lower part of the hierarchy, when it has locally cached the higher part of hierarchy.<br>
The trust anchor SHOULD NOT be present in the certificate bundle, because the validator is expected to possess it.</p>
<a name="Bundle-Name-Discovery"></a>
<h2 >Bundle Name Discovery<a href="#Bundle-Name-Discovery" class="wiki-anchor">¶</a></h2>
<p>This section defines two common methods of finding certificate bundle name.<br>
Application MAY define additional methods.</p>
<p>Name of a Data segment within a bundle is the bundle name plus a segment number component.</p>
<a name="Deriving-from-Certificate-Name"></a>
<h3 >Deriving from Certificate Name<a href="#Deriving-from-Certificate-Name" class="wiki-anchor">¶</a></h3>
<p>Every certificate SHOULD be published together with a certificate bundle.<br>
For a certificate named <code>/<SubjectName>/KEY/[KeyId]/[IssuerId]/[Version]</code>, its bundle SHOULD be named <code>/<SubjectName>/KEY/[KeyId]/32=cert-bundle/[IssuerId]/[Version]</code>.</p>
<p>KeyLocator name normally ends at <code>[KeyId]</code>.<br>
Therefore, the <code>32=cert-bundle</code> component is inserted after <code>[KeyId]</code>, enabling a fetcher to derive bundle name from KeyLocator.</p>
<a name="Provided-in-RDR-Metadata"></a>
<h3 >Provided in RDR Metadata<a href="#Provided-in-RDR-Metadata" class="wiki-anchor">¶</a></h3>
<p>A producer MAY provide one or more certificate bundle names in the <a href="https://redmine.named-data.net/projects/ndn-tlv/wiki/RDR" class="external">RDR metadata</a>.<br>
These certificate bundles SHOULD enable efficient validation of the RDR metadata packet itself, as well as all Data packets under the versioned name.</p>
<p>A bundle name is enclosed in an <code>CertBundle</code> TLV in RDR metadata's Content element:</p>
<pre><code class="xml syntaxhl" data-language="xml"><span class="nt"><CertBundle></span>
<span class="nt"><Name></span>/subject/KEY/id/32=cert-bundle/issuer/35=%01<span class="nt"></Name></span>
<span class="nt"></CertBundle></span>
</code></pre>
<p>In the second example, two certificate bundle names are listed.<br>
It is not required to include all certificates necessary to validate a packet in a single bundle.<br>
The publisher MAY use multiple bundles to collectively provide certificates:</p>
<pre><code class="xml syntaxhl" data-language="xml"><span class="nt"><CertBundle></span>
<span class="nt"><Name></span>/first/32=cert-bundle<span class="nt"></Name></span>
<span class="nt"></CertBundle></span>
<span class="nt"><CertBundle></span>
<span class="nt"><Name></span>/second/32=cert-bundle/xx<span class="nt"></Name></span>
<span class="nt"></CertBundle></span>
</code></pre>
<p>The producer MAY indicate the number of segments in a certificate bundle to allow more efficient retrieval, using a <code>SegmentNameComponent</code> reflecting the last segment number:</p>
<pre><code class="xml syntaxhl" data-language="xml"><span class="nt"><CertBundle></span>
<span class="nt"><Name></span>/subject/KEY/id/32=cert-bundle/issuer/35=%01<span class="nt"></Name></span>
<span class="nt"><SegmentNameComponent></span>4<span class="nt"></SegmentNameComponent></span>
<span class="nt"></CertBundle></span>
</code></pre>
<p><code>CertBundle</code> TLV-TYPE is taken from application range.<br>
Unrecognized elements under <code>CertBundle</code> TLV follow TLV evolvability guidelines.</p>
<a name="Low-Level-API"></a>
<h2 >Low Level API<a href="#Low-Level-API" class="wiki-anchor">¶</a></h2>
<pre><code class="cpp syntaxhl" data-language="cpp"><span class="cm">/** \brief Derive certificate bundle name from certificate name.
*/</span>
<span class="n">Name</span>
<span class="nf">deriveCertBundleName</span><span class="p">(</span><span class="k">const</span> <span class="n">Name</span><span class="o">&</span> <span class="n">certName</span><span class="p">);</span>
<span class="c1">// Example: deriveCertBundleName("/subject/KEY/id/issuer/35=%01") == "/subject/KEY/id/32=cert-bundle/issuer/35=%01"</span>
<span class="cm">/** \brief Derive certificate bundle name prefix from KeyLocator.
*/</span>
<span class="n">Name</span>
<span class="nf">deriveCertBundlePrefixFromKeyLocator</span><span class="p">(</span><span class="k">const</span> <span class="n">KeyLocator</span><span class="o">&</span> <span class="n">kl</span><span class="p">);</span>
<span class="c1">// Example: deriveCertBundlePrefixFromKeyLocator(KeyLocator("/subject/KEY/id")) == "/subject/KEY/id/32=cert-bundle"</span>
<span class="cm">/** \brief Encode a certificate bundle.
* \param certificates Certificates to be included in the bundle.
* \param bundleName name of bundle packets, excluding the segment number.
* \param keyChain KeyChain used to sign bundle packets.
* \param si SigningInfo used to sign bundle packets.
*/</span>
<span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">Data</span><span class="o">></span>
<span class="n">encodeCertBundle</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">Certificate</span><span class="o">>&</span> <span class="n">certificates</span><span class="p">,</span> <span class="k">const</span> <span class="n">Name</span><span class="o">&</span> <span class="n">bundleName</span><span class="p">,</span>
<span class="n">KeyChain</span><span class="o">&</span> <span class="n">keyChain</span><span class="p">,</span> <span class="k">const</span> <span class="n">SigningInfo</span><span class="o">&</span> <span class="n">si</span><span class="p">);</span>
<span class="c1">// This function should internally use SegmentPublisher.</span>
<span class="cm">/** \brief Decode a certificate bundle.
*/</span>
<span class="k">class</span> <span class="nc">CertBundleDecoder</span>
<span class="p">{</span>
<span class="nl">public:</span>
<span class="n">signal</span><span class="o">::</span><span class="n">Signal</span><span class="o"><</span><span class="n">CertBundleDecoder</span><span class="p">,</span> <span class="n">Certificate</span><span class="o">></span> <span class="n">certAvailable</span><span class="p">;</span>
<span class="cm">/** \brief Append an arrived segment.
* \pre Prior segments, if any, has arrived.
*/</span>
<span class="kt">void</span>
<span class="n">append</span><span class="p">(</span><span class="k">const</span> <span class="n">Data</span><span class="o">&</span> <span class="n">segment</span><span class="p">);</span>
<span class="p">};</span>
<span class="c1">// This is a stream decoder: it can decode segments as they arrive in order, and does not need to</span>
<span class="c1">// wait for the entire certificate bundle to be retrieved. This allows a fetcher to stop retrieving</span>
<span class="c1">// later segments if it has collected enough certificate for validating a packet.</span>
<span class="cm">/** \brief Name and optionally segment count of a segmented object.
*/</span>
<span class="k">struct</span> <span class="nc">SegmentedObjectRef</span>
<span class="p">{</span>
<span class="n">Name</span> <span class="n">prefix</span><span class="p">;</span>
<span class="n">optional</span><span class="o"><</span><span class="kt">uint64_t</span><span class="o">></span> <span class="n">lastSegNum</span><span class="p">;</span>
<span class="p">};</span>
<span class="c1">// extending existing type</span>
<span class="k">class</span> <span class="nc">MetadataObject</span>
<span class="p">{</span>
<span class="nl">public:</span>
<span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">SegmentedObjectRef</span><span class="o">>&</span>
<span class="n">getCertBundles</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
<span class="n">MetadataObject</span><span class="o">&</span>
<span class="n">setCertBundles</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">SegmentedObjectRef</span><span class="o">></span> <span class="n">certBundles</span><span class="p">);</span>
<span class="p">};</span>
</code></pre>
<p>Instead of having these as static methods in publisher and fetcher APIs, this design opts to have separate low level APIs, so that logic and communication are separated. This separation improves modularity and testability.</p>
<a name="Publisher-API"></a>
<h2 >Publisher API<a href="#Publisher-API" class="wiki-anchor">¶</a></h2>
<pre><code class="cpp syntaxhl" data-language="cpp"><span class="cm">/** \brief A certificate bundle being created and published.
*/</span>
<span class="k">class</span> <span class="nc">CertBundleHandle</span>
<span class="p">{</span>
<span class="nl">public:</span>
<span class="k">const</span> <span class="n">Name</span><span class="o">&</span>
<span class="n">getBundleName</span><span class="p">();</span>
<span class="k">enum</span> <span class="n">State</span> <span class="p">{</span>
<span class="n">PENDING</span><span class="p">,</span> <span class="c1">///< bundle is being created</span>
<span class="n">READY</span><span class="p">,</span> <span class="c1">///< bundle is published</span>
<span class="n">FAILED</span><span class="p">,</span> <span class="c1">///< bundle creation has failed</span>
<span class="n">UNPUBLISHED</span><span class="p">,</span> <span class="c1">///< bundle creation is canceled and bundle should be unpublished</span>
<span class="p">};</span>
<span class="cm">/** \brief Get bundle creation and publishing state.
*/</span>
<span class="n">State</span>
<span class="n">getState</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
<span class="cm">/** \brief Emitted when state has changed.
*/</span>
<span class="n">signal</span><span class="o">::</span><span class="n">Signal</span><span class="o"><</span><span class="n">X</span><span class="p">,</span> <span class="n">State</span><span class="o">>&</span> <span class="n">afterStateChange</span><span class="p">;</span>
<span class="c1">// CertBundleHandle type must be copyable. Thus, this signal must live elsewhere</span>
<span class="c1">// (e.g. an internal struct owned by CertBundleBuilder) and only a reference is stored.</span>
<span class="cm">/** \brief Get last error during bundle creation.
* \pre getState() == FAILED
*/</span>
<span class="n">std</span><span class="o">::</span><span class="n">tuple</span><span class="o"><</span><span class="kt">int</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">></span>
<span class="n">getError</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
<span class="cm">/** \brief Get number of certificates included in the bundle.
* \pre getState() == READY
*/</span>
<span class="kt">size_t</span>
<span class="n">countCerts</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
<span class="cm">/** \brief Obtain bundle packets.
* \pre getState() == READY
*/</span>
<span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">Data</span><span class="o">>&</span>
<span class="n">get</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
<span class="cm">/** \brief Cancel bundle creation and unpublish.
*/</span>
<span class="kt">void</span>
<span class="n">cancel</span><span class="p">();</span>
<span class="p">};</span>
<span class="cm">/** \brief Unpublish certificate bundle upon destruction.
*/</span>
<span class="k">class</span> <span class="nc">ScopedCertBundleHandle</span><span class="p">;</span>
<span class="cm">/** \brief Create certificate bundles.
*/</span>
<span class="k">class</span> <span class="nc">CertBundleBuilder</span>
<span class="p">{</span>
<span class="nl">public:</span>
<span class="cm">/** \brief Constructor.
* \param keyChain KeyChain used to sign bundle packets.
* CertBundleBuilder can also collect certificates from its PIB.
* \param si SigningInfo used to sign bundle packets.
*/</span>
<span class="n">CertBundleBuilder</span><span class="p">(</span><span class="n">KeyChain</span><span class="o">&</span> <span class="n">keyChain</span><span class="p">,</span> <span class="k">const</span> <span class="n">SigningInfo</span><span class="o">&</span> <span class="n">si</span><span class="p">);</span>
<span class="cm">/** \brief Enable collecting certificates from a CertificateStorage.
*/</span>
<span class="kt">void</span>
<span class="n">setStorage</span><span class="p">(</span><span class="n">CertificateStorage</span><span class="o">&</span> <span class="n">storage</span><span class="p">);</span>
<span class="cm">/** \brief Enable retrieving certificates using a CertificateFetcher.
* \pre setStorage has been invoked.
*/</span>
<span class="kt">void</span>
<span class="n">setFetcher</span><span class="p">(</span><span class="n">CertificateFetcher</span><span class="o">&</span> <span class="n">fetcher</span><span class="p">);</span>
<span class="cm">/** \brief Emitted when \c publish is invoked.
*
* This allows an external component to know when a new certificate bundle is being
* created and hook onto its signals.
*/</span>
<span class="n">signal</span><span class="o">::</span><span class="n">Signal</span><span class="o"><</span><span class="n">CertBundleBuilder</span><span class="p">,</span> <span class="n">CertBundleHandle</span><span class="o">></span> <span class="n">afterAdd</span><span class="p">;</span>
<span class="cm">/** \brief Start preparing and publishing a certificate bundle.
*/</span>
<span class="n">CertBundleHandle</span>
<span class="n">add</span><span class="p">(</span><span class="k">const</span> <span class="n">Name</span><span class="o">&</span> <span class="n">certName</span><span class="p">,</span> <span class="k">const</span> <span class="n">Name</span><span class="o">&</span> <span class="n">bundleName</span><span class="p">);</span>
<span class="n">CertBundleHandle</span>
<span class="n">add</span><span class="p">(</span><span class="k">const</span> <span class="n">Name</span><span class="o">&</span> <span class="n">certName</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">return</span> <span class="n">add</span><span class="p">(</span><span class="n">certName</span><span class="p">,</span> <span class="n">deriveCertBundleName</span><span class="p">(</span><span class="n">certName</span><span class="p">));</span>
<span class="p">}</span>
<span class="p">};</span>
<span class="c1">// This type builds certificate bundles starting from leaf certificate names passed to add() method.</span>
<span class="c1">// It can collect intermediate certificates from the local KeyChain, caches in a</span>
<span class="c1">// CertificateStorage, or the network via a fetcher. This type exposes prepared bundles via signals,</span>
<span class="c1">// but does not make them available for retrieval by itself. This design features a separation of</span>
<span class="c1">// responsibilities, with this type being responsible for building certificate bundles, while other</span>
<span class="c1">// types listed below are responsible for publishing them.</span>
<span class="cm">/** \brief Insert certificate bundles to an InMemoryStorage.
*/</span>
<span class="k">class</span> <span class="nc">CertBundleImsInserter</span>
<span class="p">{</span>
<span class="nl">public:</span>
<span class="cm">/** \brief Constructor.
* \p wantDelete whether to delete bundle packets when bundle is unpublished.
*/</span>
<span class="n">CertBundleImsInserter</span><span class="p">(</span><span class="n">CertBundleBuilder</span><span class="o">&</span> <span class="n">cbb</span><span class="p">,</span> <span class="n">InMemoryStorage</span><span class="o">&</span> <span class="n">ims</span><span class="p">,</span> <span class="kt">bool</span> <span class="n">wantDelete</span> <span class="o">=</span> <span class="nb">true</span><span class="p">);</span>
<span class="p">};</span>
<span class="cm">/** \brief Serve certificate bundles on a face.
*/</span>
<span class="k">class</span> <span class="nc">CertBundleProducer</span>
<span class="p">{</span>
<span class="nl">public:</span>
<span class="cm">/** \brief Constructor.
* \p wantRegisterPrefix if true, each bundle registers a prefix on the local forwarder;
* otherwise, each bundle creates an InterestFilter only.
*/</span>
<span class="n">CertBundleProducer</span><span class="p">(</span><span class="n">CertBundleBuilder</span><span class="o">&</span> <span class="n">cbb</span><span class="p">,</span> <span class="n">Face</span><span class="o">&</span> <span class="n">face</span><span class="p">,</span> <span class="kt">bool</span> <span class="n">wantRegisterPrefix</span> <span class="o">=</span> <span class="nb">true</span><span class="p">);</span>
<span class="n">Face</span><span class="o">&</span>
<span class="n">getFace</span><span class="p">();</span>
<span class="cm">/** \brief Emitted when a certificate bundle has been published and is available for retrieval.
*/</span>
<span class="n">signal</span><span class="o">::</span><span class="n">Signal</span><span class="o"><</span><span class="n">CertBundleProducer</span><span class="p">,</span> <span class="n">CertBundleHandle</span><span class="o">></span> <span class="n">afterPublish</span><span class="p">;</span>
<span class="c1">// If prefix registration is necessary, this is emitted after prefix registration is completed.</span>
<span class="p">};</span>
<span class="cm">/** \brief Insert certificate bundles to repo-ng.
*/</span>
<span class="k">class</span> <span class="nc">CertBundleRepongInserter</span>
<span class="p">{</span>
<span class="nl">public:</span>
<span class="cm">/** \brief Constructor.
* \p wantDelete whether to delete bundle packets when bundle is unpublished.
*/</span>
<span class="n">CertBundleRepongInserter</span><span class="p">(</span><span class="n">CertBundleProducer</span><span class="o">&</span> <span class="n">cbp</span><span class="p">,</span> <span class="k">const</span> <span class="n">Name</span><span class="o">&</span> <span class="n">repoCommandPrefix</span><span class="p">,</span>
<span class="kt">bool</span> <span class="n">wantDelete</span> <span class="o">=</span> <span class="nb">false</span><span class="p">);</span>
<span class="p">};</span>
<span class="c1">// This type should hook onto CertBundleProducer::afterPublish signal, and send a repo insertion</span>
<span class="c1">// command after a bundle is available for retrieval.</span>
<span class="c1">// If wantDelete is requested, this type should also send a repo deletion command when a bundle</span>
<span class="c1">// is unpublished.</span>
</code></pre>
<a name="Fetcher-API"></a>
<h2 >Fetcher API<a href="#Fetcher-API" class="wiki-anchor">¶</a></h2>
<pre><code class="cpp syntaxhl" data-language="cpp"><span class="k">class</span> <span class="nc">CertBundleFetcher</span>
<span class="p">{</span>
<span class="nl">public:</span>
<span class="k">struct</span> <span class="nc">Options</span>
<span class="p">{</span>
<span class="c1">/// maximum number of certificate bundles allowed for each original packet</span>
<span class="kt">int</span> <span class="n">maxBundles</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
<span class="c1">/// InterestLifetime for bundle Interest</span>
<span class="n">time</span><span class="o">::</span><span class="n">milliseconds</span> <span class="n">interestLifetime</span> <span class="o">=</span> <span class="mi">3000</span><span class="n">_ms</span><span class="p">;</span>
<span class="c1">/// bundle fetching options</span>
<span class="n">SegmentFetcher</span><span class="o">::</span><span class="n">Options</span> <span class="n">segmentFetcherOptions</span><span class="p">;</span>
<span class="c1">/// whether to send Interest with NextHopFaceId when available</span>
<span class="kt">bool</span> <span class="n">wantDirectFetch</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
<span class="c1">/// whether to send Interest without NextHopFaceId; implied true if wantDirectFetch is false</span>
<span class="c1">/// or NextHopFaceId is unavailable</span>
<span class="kt">bool</span> <span class="n">wantNormalFetch</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
<span class="p">};</span>
<span class="c1">// retransmitInterval is separate from interestLifetime, so that Interest is retransmitted before</span>
<span class="c1">// PIT entry disappears, allowing strategy to make better decisions based on PIT entry.</span>
<span class="c1">// This behavior should be implemented in DataFetcher, imported from ndncatchunks.</span>
<span class="n">CertBundleFetcher</span><span class="p">(</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">CertificateFetcher</span><span class="o">></span> <span class="n">inner</span><span class="p">,</span> <span class="n">Face</span><span class="o">&</span> <span class="n">face</span><span class="p">,</span>
<span class="k">const</span> <span class="n">Options</span><span class="o">&</span> <span class="n">options</span> <span class="o">=</span> <span class="n">Options</span><span class="p">());</span>
<span class="cm">/** \brief Indicate the certificate bundle at \p bundleName contains certificates necessary to
* validate packets under \p prefix .
*/</span>
<span class="kt">void</span>
<span class="n">addBundle</span><span class="p">(</span><span class="k">const</span> <span class="n">Name</span><span class="o">&</span> <span class="n">prefix</span><span class="p">,</span> <span class="k">const</span> <span class="n">Name</span><span class="o">&</span> <span class="n">bundleName</span><span class="p">,</span> <span class="n">optional</span><span class="o"><</span><span class="kt">uint64_t</span><span class="o">></span> <span class="n">lastSegNum</span><span class="p">);</span>
<span class="c1">// Application should register bundle names from an RDR metadata packet with this function,</span>
<span class="c1">// so that the fetcher would retrieve the specified bundles.</span>
<span class="p">};</span>
<span class="c1">// Upon receiving a certificate request, this fetcher retrieves a certificate bundle registered by</span>
<span class="c1">// addBundle() if matched, or deriveCertBundleName(certName) otherwise. If a certificate bundle</span>
<span class="c1">// does not contain all necessary certificates for an original packet (i.e. ValidationState),</span>
<span class="c1">// another certificate request would arrive; this fetcher may fetch another bundle until the limit</span>
<span class="c1">// given in Options::maxBundles is reached, after which all requests are redirected to the inner</span>
<span class="c1">// fetcher.</span>
<span class="c1">//</span>
<span class="c1">// Retrieval of a single certificate bundle should be handled by SegmentFetcher. SegmentFetcher</span>
<span class="c1">// must be extended with:</span>
<span class="c1">// (1) a signal that is emitted a segment arrives in order and has been validated;</span>
<span class="c1">// (2) ability to send Interests with NextHopFaceId;</span>
<span class="c1">// (3) ability to set known last segment number.</span>
<span class="c1">// This fetcher hooks onto the segment in-order arrival signal and passes the segment to an internal</span>
<span class="c1">// CertBundleDecoder, and inserts decoded certificates into the CertificateStorage.</span>
<span class="c1">//</span>
<span class="c1">// If bundle retrieval fails (after SegmentFetcher has exhausted its retries), this fetcher passes</span>
<span class="c1">// the certificate request to the inner fetcher. The next certificate request may start a new</span>
<span class="c1">// bundle retrieval subject to Options::maxBundles limit, as described above.</span>
</code></pre> ndn-cxx - Feature #2766: CertificateBundle: designhttps://redmine.named-data.net/issues/2766?journal_id=253362019-05-15T14:52:02ZJunxiao Shi
<ul><li><strong>Blocks</strong> deleted (<i><a class="issue tracker-2 status-9 priority-2 priority-default closed" href="/issues/3892">Feature #3892</a>: Integrate publishing of KeyBundle into Face::setInterestFilter</i>)</li></ul> ndn-cxx - Feature #2766: CertificateBundle: designhttps://redmine.named-data.net/issues/2766?journal_id=257442019-08-27T20:52:34ZDavide Pesavento
<ul><li><strong>Target version</strong> changed from <i>v0.7</i> to <i>0.8.0</i></li></ul> ndn-cxx - Feature #2766: CertificateBundle: designhttps://redmine.named-data.net/issues/2766?journal_id=258302019-09-24T13:50:44ZJunxiao Shi
<ul><li><strong>Tags</strong> set to <i>CertificateBundle</i></li><li><strong>Status</strong> changed from <i>Feedback</i> to <i>Closed</i></li><li><strong>% Done</strong> changed from <i>60</i> to <i>100</i></li></ul><p>Closing because there's no objection on this design.<br>
Implementation tasks have been created: <a class="issue tracker-2 status-2 priority-2 priority-default" title="Feature: CertificateBundle encoding and decoding (In Progress)" href="https://redmine.named-data.net/issues/5004">#5004</a> <a class="issue tracker-2 status-1 priority-2 priority-default" title="Feature: CertificateBundle publisher (New)" href="https://redmine.named-data.net/issues/5005">#5005</a> <a class="issue tracker-2 status-1 priority-2 priority-default" title="Feature: CertificateBundle producer (New)" href="https://redmine.named-data.net/issues/5006">#5006</a> <a class="issue tracker-2 status-1 priority-2 priority-default" title="Feature: CertificateBundle fetcher (New)" href="https://redmine.named-data.net/issues/5007">#5007</a>.</p>
ndn-cxx - Feature #2766: CertificateBundle: designhttps://redmine.named-data.net/issues/2766?journal_id=266772020-05-18T16:03:15ZDavide Pesavento
<ul></ul><blockquote>
<p>ContentType MUST be omitted.</p>
</blockquote>
<p>Why?</p>
<blockquote>
<p>The producer MAY indicate the number of segments in a certificate bundle [...] using a SegmentNameComponent reflecting the last segment number</p>
</blockquote>
<p>Why not a <code>FinalBlockId</code>?</p>
ndn-cxx - Feature #2766: CertificateBundle: designhttps://redmine.named-data.net/issues/2766?journal_id=266782020-05-18T16:46:11ZJunxiao Shi
<ul></ul><blockquote>
<blockquote>
<p>ContentType MUST be omitted.</p>
</blockquote>
<p>Why?</p>
</blockquote>
<p>The name alone identifies the content type. There's no need for additional identification.<br>
Allowing "blob" type doesn't convey additional meaning, but only wastes bytes.</p>
<blockquote>
<blockquote>
<p>The producer MAY indicate the number of segments in a certificate bundle [...] using a SegmentNameComponent reflecting the last segment number</p>
</blockquote>
<p>Why not a <code>FinalBlockId</code>?</p>
</blockquote>
<p>The bundle spec is defined to adopt Naming Conventions rev2, so there's no need for wrapping into FinalBlockId.</p>
ndn-cxx - Feature #2766: CertificateBundle: designhttps://redmine.named-data.net/issues/2766?journal_id=266792020-05-18T17:20:07ZDavide Pesavento
<ul></ul><p>Junxiao Shi wrote:</p>
<blockquote>
<blockquote>
<blockquote>
<p>ContentType MUST be omitted.</p>
</blockquote>
<p>Why?</p>
</blockquote>
<p>The name alone identifies the content type. There's no need for additional identification.<br>
Allowing "blob" type doesn't convey additional meaning, but only wastes bytes.</p>
</blockquote>
<p><code>32=cert-bundle</code> is 13 bytes, certificates are hundreds of bytes each... and you're worried about 3 bytes?</p>
<blockquote>
<blockquote>
<blockquote>
<p>The producer MAY indicate the number of segments in a certificate bundle [...] using a SegmentNameComponent reflecting the last segment number</p>
</blockquote>
<p>Why not a <code>FinalBlockId</code>?</p>
</blockquote>
<p>The bundle spec is defined to adopt Naming Conventions rev2, so there's no need for wrapping into FinalBlockId.</p>
</blockquote>
<p>Still, <code>FinalBlockId</code> sounds more general to me.</p>
ndn-cxx - Feature #2766: CertificateBundle: designhttps://redmine.named-data.net/issues/2766?journal_id=266802020-05-18T17:28:28ZJunxiao Shi
<ul></ul><blockquote>
<blockquote>
<blockquote>
<blockquote>
<p>ContentType MUST be omitted.</p>
</blockquote>
<p>Why?</p>
</blockquote>
<p>The name alone identifies the content type. There's no need for additional identification.<br>
Allowing "blob" type doesn't convey additional meaning, but only wastes bytes.</p>
</blockquote>
<p><code>32=cert-bundle</code> is 13 bytes, certificates are hundreds of bytes each... and you're worried about 3 bytes?</p>
</blockquote>
<p>Not just that. Disallowing ContentType improves the uniqueness of encodings.<br>
Yes I know non-uniqueness could come from many other places, but it's better to reduce such places than to introduce them.<br>
And no, other older protocols that allow such ambiguity are not reasons for this protocol to make the same mistake.</p>
<blockquote>
<blockquote>
<blockquote>
<blockquote>
<p>The producer MAY indicate the number of segments in a certificate bundle [...] using a SegmentNameComponent reflecting the last segment number</p>
</blockquote>
<p>Why not a <code>FinalBlockId</code>?</p>
</blockquote>
<p>The bundle spec is defined to adopt Naming Conventions rev2, so there's no need for wrapping into FinalBlockId.</p>
</blockquote>
<p>Still, <code>FinalBlockId</code> sounds more general to me.</p>
</blockquote>
<p>No, this is an application layer protocol and there's no reason to copy from network layer.</p>
ndn-cxx - Feature #2766: CertificateBundle: designhttps://redmine.named-data.net/issues/2766?journal_id=281562023-12-01T20:29:29ZDavide Pesavento
<ul><li><strong>Blocks</strong> deleted (<i><a class="issue tracker-3 status-1 priority-2 priority-default" href="/issues/3950">Task #3950</a>: Use CertificateBundleFetcher instead of DirectFetcher</i>)</li></ul>