<div dir="ltr"><div dir="ltr"><div>Hi Zhiyi</div><div><br></div><div>I'm trying to implement the protocol in NDNts. I've pasted my implementation of the crypto operations at the end of this message.<br></div><div>I have unit-tested these operations and they seem to be working. Since Node.js implements crypto via OpenSSL, this implies OpenSSL has sufficient primitives for crypto needed by NDNCERT.</div><br><div>I noticed some more issues in the protocol.<br></div><div><br></div><div><br></div><div>
<div>Several steps specify the use of signed Interest.</div><div>They should also specify which uniqueness assurance fields are required in the SignatureInfo: SignatureNonce, SignatureTime, SignatureSeqNum.<br></div><div><br></div><div><br></div><div>Several steps specify MustBeFresh in Interest, but lacks FreshnessPeriod in Data. A Data without FreshnessPeriod cannot satisfy an Interest with MustBeFresh.</div><div>Given signed Interests are unique, it's unnecessary to include MustBeFresh.</div><div><br></div><div><br></div><div>Several TLVs are specified as <span style="font-family:monospace">*OCTET</span> in ABNF, but text says "human readable string".</div><div>It also needs to specify what codec to use, such as UTF-8. If you want to restrict to ASCII instead, specify as <span style="font-family:monospace">*CHAR</span>.<br></div>

CA profile packet should have FinalBlockId (set to the same as last name component), so that it is compatible with segmentation convention.<br></div><div><br></div><div><br></div><div>NEW response uses "challenge" TLV-TYPE, but it lacks number assignment.</div><div><br></div><div><br></div><div>The AES-GCM session key is established by ECDH followed by HKDF.</div><div>WebCrypto cannot directly derive the HKDF key from ECDH. Instead, the workflow is:</div><div><ol><li>derive bits from ECDH</li><li>import bits as HKDF key</li><li>derive AES-GCM key from HKDF key<br></li></ol></div><div>The protocol specifies that the AES-GCM key is 128 bits. However, it does not specify how many bits go into the HKDF key.</div><div>Given ECDH on P-256 curve can establish a shared secret of 256 bits, I'd recommend specifying 256 bits.</div><div><br></div><div><br></div><div>In PROBE/CHALLENGE request, parameter-value is specified as a string.<br></div><div>Some probe methods and challenges may natively use binary information. Thus, this field could be defined as binary instead.</div><div>parameter-key could stay as string, and defined as *CHAR if restricted to ASCII.<br></div><div><br></div><div><br></div><div>Yours, Junxiao<br></div></div><div><br></div><div><br></div><div><br></div><div>

<div style="color:rgb(212,212,212);background-color:rgb(30,30,30);font-family:Consolas,"Courier New",monospace;font-weight:normal;font-size:14px;line-height:19px;white-space:pre"><div><span style="color:rgb(86,156,214)">const</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(156,220,254)">ECDH_PARAMS</span><span style="color:rgb(212,212,212)">: </span><span style="color:rgb(78,201,176)">EcKeyGenParams</span><span style="color:rgb(212,212,212)"> & </span><span style="color:rgb(78,201,176)">EcKeyImportParams</span><span style="color:rgb(212,212,212)"> = {</span></div><div><span style="color:rgb(212,212,212)">  </span><span style="color:rgb(156,220,254)">name</span><span style="color:rgb(156,220,254)">:</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(206,145,120)">"ECDH"</span><span style="color:rgb(212,212,212)">,</span></div><div><span style="color:rgb(212,212,212)">  </span><span style="color:rgb(156,220,254)">namedCurve</span><span style="color:rgb(156,220,254)">:</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(206,145,120)">"P-256"</span><span style="color:rgb(212,212,212)">,</span></div><div><span style="color:rgb(212,212,212)">};</span></div><br><div><span style="color:rgb(197,134,192)">export</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(86,156,214)">async</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(86,156,214)">function</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(220,220,170)">generateEcdhKey</span><span style="color:rgb(212,212,212)">(): </span><span style="color:rgb(78,201,176)">Promise</span><span style="color:rgb(212,212,212)"><</span><span style="color:rgb(78,201,176)">CryptoKeyPair</span><span style="color:rgb(212,212,212)">> {</span></div><div><span style="color:rgb(212,212,212)">  </span><span style="color:rgb(197,134,192)">return</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(156,220,254)">crypto</span><span style="color:rgb(212,212,212)">.</span><span style="color:rgb(156,220,254)">subtle</span><span style="color:rgb(212,212,212)">.</span><span style="color:rgb(220,220,170)">generateKey</span><span style="color:rgb(212,212,212)">(</span><span style="color:rgb(156,220,254)">ECDH_PARAMS</span><span style="color:rgb(212,212,212)">, </span><span style="color:rgb(86,156,214)">false</span><span style="color:rgb(212,212,212)">, [</span><span style="color:rgb(206,145,120)">"deriveBits"</span><span style="color:rgb(212,212,212)">]);</span></div><div><span style="color:rgb(212,212,212)">}</span></div><br><div><span style="color:rgb(197,134,192)">export</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(86,156,214)">async</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(86,156,214)">function</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(220,220,170)">importEcdhPub</span><span style="color:rgb(212,212,212)">(</span><span style="color:rgb(156,220,254)">raw</span><span style="color:rgb(212,212,212)">: </span><span style="color:rgb(78,201,176)">Uint8Array</span><span style="color:rgb(212,212,212)">): </span><span style="color:rgb(78,201,176)">Promise</span><span style="color:rgb(212,212,212)"><</span><span style="color:rgb(78,201,176)">CryptoKey</span><span style="color:rgb(212,212,212)">> {</span></div><div><span style="color:rgb(212,212,212)">  </span><span style="color:rgb(197,134,192)">return</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(156,220,254)">crypto</span><span style="color:rgb(212,212,212)">.</span><span style="color:rgb(156,220,254)">subtle</span><span style="color:rgb(212,212,212)">.</span><span style="color:rgb(220,220,170)">importKey</span><span style="color:rgb(212,212,212)">(</span><span style="color:rgb(206,145,120)">"raw"</span><span style="color:rgb(212,212,212)">, </span><span style="color:rgb(156,220,254)">raw</span><span style="color:rgb(212,212,212)">, </span><span style="color:rgb(156,220,254)">ECDH_PARAMS</span><span style="color:rgb(212,212,212)">, </span><span style="color:rgb(86,156,214)">true</span><span style="color:rgb(212,212,212)">, []);</span></div><div><span style="color:rgb(212,212,212)">}</span></div><br><div><span style="color:rgb(197,134,192)">export</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(86,156,214)">async</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(86,156,214)">function</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(220,220,170)">exportEcdhPub</span><span style="color:rgb(212,212,212)">(</span><span style="color:rgb(156,220,254)">key</span><span style="color:rgb(212,212,212)">: </span><span style="color:rgb(78,201,176)">CryptoKey</span><span style="color:rgb(212,212,212)">): </span><span style="color:rgb(78,201,176)">Promise</span><span style="color:rgb(212,212,212)"><</span><span style="color:rgb(78,201,176)">Uint8Array</span><span style="color:rgb(212,212,212)">> {</span></div><div><span style="color:rgb(212,212,212)">  </span><span style="color:rgb(86,156,214)">const</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(156,220,254)">raw</span><span style="color:rgb(212,212,212)"> = </span><span style="color:rgb(197,134,192)">await</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(156,220,254)">crypto</span><span style="color:rgb(212,212,212)">.</span><span style="color:rgb(156,220,254)">subtle</span><span style="color:rgb(212,212,212)">.</span><span style="color:rgb(220,220,170)">exportKey</span><span style="color:rgb(212,212,212)">(</span><span style="color:rgb(206,145,120)">"raw"</span><span style="color:rgb(212,212,212)">, </span><span style="color:rgb(156,220,254)">key</span><span style="color:rgb(212,212,212)">);</span></div><div><span style="color:rgb(212,212,212)">  </span><span style="color:rgb(197,134,192)">return</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(86,156,214)">new</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(78,201,176)">Uint8Array</span><span style="color:rgb(212,212,212)">(</span><span style="color:rgb(156,220,254)">raw</span><span style="color:rgb(212,212,212)">);</span></div><div><span style="color:rgb(212,212,212)">}</span></div><br><div><span style="color:rgb(197,134,192)">export</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(86,156,214)">async</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(86,156,214)">function</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(220,220,170)">makeSessionKey</span><span style="color:rgb(212,212,212)">(</span></div><div><span style="color:rgb(212,212,212)">    </span><span style="color:rgb(156,220,254)">ecdhPvt</span><span style="color:rgb(212,212,212)">: </span><span style="color:rgb(78,201,176)">CryptoKey</span><span style="color:rgb(212,212,212)">,</span></div><div><span style="color:rgb(212,212,212)">    </span><span style="color:rgb(156,220,254)">ecdhPub</span><span style="color:rgb(212,212,212)">: </span><span style="color:rgb(78,201,176)">CryptoKey</span><span style="color:rgb(212,212,212)">,</span></div><div><span style="color:rgb(212,212,212)">    </span><span style="color:rgb(156,220,254)">salt</span><span style="color:rgb(212,212,212)">: </span><span style="color:rgb(78,201,176)">Uint8Array</span><span style="color:rgb(212,212,212)">,</span></div><div><span style="color:rgb(212,212,212)">    </span><span style="color:rgb(156,220,254)">requestId</span><span style="color:rgb(212,212,212)">: </span><span style="color:rgb(78,201,176)">Uint8Array</span><span style="color:rgb(212,212,212)">,</span></div><div><span style="color:rgb(212,212,212)">): </span><span style="color:rgb(78,201,176)">Promise</span><span style="color:rgb(212,212,212)"><</span><span style="color:rgb(78,201,176)">CryptoKey</span><span style="color:rgb(212,212,212)">> {</span></div><div><span style="color:rgb(212,212,212)">  </span><span style="color:rgb(86,156,214)">const</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(156,220,254)">hkdfBits</span><span style="color:rgb(212,212,212)"> = </span><span style="color:rgb(197,134,192)">await</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(156,220,254)">crypto</span><span style="color:rgb(212,212,212)">.</span><span style="color:rgb(156,220,254)">subtle</span><span style="color:rgb(212,212,212)">.</span><span style="color:rgb(220,220,170)">deriveBits</span><span style="color:rgb(212,212,212)">({ </span><span style="color:rgb(156,220,254)">name</span><span style="color:rgb(156,220,254)">:</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(206,145,120)">"ECDH"</span><span style="color:rgb(212,212,212)">, </span><span style="color:rgb(156,220,254)">public</span><span style="color:rgb(156,220,254)">:</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(156,220,254)">ecdhPub</span><span style="color:rgb(212,212,212)"> }, </span><span style="color:rgb(156,220,254)">ecdhPvt</span><span style="color:rgb(212,212,212)">, </span><span style="color:rgb(181,206,168)">256</span><span style="color:rgb(212,212,212)">);</span></div><div><span style="color:rgb(212,212,212)">  </span><span style="color:rgb(86,156,214)">const</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(156,220,254)">hkdfKey</span><span style="color:rgb(212,212,212)"> = </span><span style="color:rgb(197,134,192)">await</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(156,220,254)">crypto</span><span style="color:rgb(212,212,212)">.</span><span style="color:rgb(156,220,254)">subtle</span><span style="color:rgb(212,212,212)">.</span><span style="color:rgb(220,220,170)">importKey</span><span style="color:rgb(212,212,212)">(</span><span style="color:rgb(206,145,120)">"raw"</span><span style="color:rgb(212,212,212)">, </span><span style="color:rgb(156,220,254)">hkdfBits</span><span style="color:rgb(212,212,212)">, </span><span style="color:rgb(206,145,120)">"HKDF"</span><span style="color:rgb(212,212,212)">, </span><span style="color:rgb(86,156,214)">false</span><span style="color:rgb(212,212,212)">, [</span><span style="color:rgb(206,145,120)">"deriveKey"</span><span style="color:rgb(212,212,212)">]);</span></div><div><span style="color:rgb(212,212,212)">  </span><span style="color:rgb(197,134,192)">return</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(156,220,254)">crypto</span><span style="color:rgb(212,212,212)">.</span><span style="color:rgb(156,220,254)">subtle</span><span style="color:rgb(212,212,212)">.</span><span style="color:rgb(220,220,170)">deriveKey</span><span style="color:rgb(212,212,212)">(</span></div><div><span style="color:rgb(212,212,212)">    {</span></div><div><span style="color:rgb(212,212,212)">      </span><span style="color:rgb(156,220,254)">name</span><span style="color:rgb(156,220,254)">:</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(206,145,120)">"HKDF"</span><span style="color:rgb(212,212,212)">,</span></div><div><span style="color:rgb(212,212,212)">      </span><span style="color:rgb(156,220,254)">salt</span><span style="color:rgb(212,212,212)">,</span></div><div><span style="color:rgb(212,212,212)">      </span><span style="color:rgb(156,220,254)">info</span><span style="color:rgb(156,220,254)">:</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(156,220,254)">requestId</span><span style="color:rgb(212,212,212)">,</span></div><div><span style="color:rgb(212,212,212)">      </span><span style="color:rgb(156,220,254)">hash</span><span style="color:rgb(156,220,254)">:</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(206,145,120)">"SHA-256"</span><span style="color:rgb(212,212,212)">,</span></div><div><span style="color:rgb(212,212,212)">    } </span><span style="color:rgb(197,134,192)">as</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(78,201,176)">any</span><span style="color:rgb(212,212,212)">,</span></div><div><span style="color:rgb(212,212,212)">    </span><span style="color:rgb(156,220,254)">hkdfKey</span><span style="color:rgb(212,212,212)">,</span></div><div><span style="color:rgb(212,212,212)">    {</span></div><div><span style="color:rgb(212,212,212)">      </span><span style="color:rgb(156,220,254)">name</span><span style="color:rgb(156,220,254)">:</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(206,145,120)">"AES-GCM"</span><span style="color:rgb(212,212,212)">,</span></div><div><span style="color:rgb(212,212,212)">      </span><span style="color:rgb(156,220,254)">length</span><span style="color:rgb(156,220,254)">:</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(181,206,168)">128</span><span style="color:rgb(212,212,212)">,</span></div><div><span style="color:rgb(212,212,212)">    },</span></div><div><span style="color:rgb(212,212,212)">    </span><span style="color:rgb(86,156,214)">false</span><span style="color:rgb(212,212,212)">,</span></div><div><span style="color:rgb(212,212,212)">    [</span><span style="color:rgb(206,145,120)">"encrypt"</span><span style="color:rgb(212,212,212)">, </span><span style="color:rgb(206,145,120)">"decrypt"</span><span style="color:rgb(212,212,212)">],</span></div><div><span style="color:rgb(212,212,212)">  );</span></div><div><span style="color:rgb(212,212,212)">}</span></div><br><div><span style="color:rgb(197,134,192)">export</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(86,156,214)">interface</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(78,201,176)">Encrypted</span><span style="color:rgb(212,212,212)"> {</span></div><div><span style="color:rgb(212,212,212)">  </span><span style="color:rgb(156,220,254)">iv</span><span style="color:rgb(212,212,212)">: </span><span style="color:rgb(78,201,176)">Uint8Array</span><span style="color:rgb(212,212,212)">;</span></div><div><span style="color:rgb(212,212,212)">  </span><span style="color:rgb(156,220,254)">ciphertext</span><span style="color:rgb(212,212,212)">: </span><span style="color:rgb(78,201,176)">Uint8Array</span><span style="color:rgb(212,212,212)">;</span></div><div><span style="color:rgb(212,212,212)">}</span></div><br><div><span style="color:rgb(197,134,192)">export</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(86,156,214)">async</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(86,156,214)">function</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(220,220,170)">sessionEncrypt</span><span style="color:rgb(212,212,212)">(</span><span style="color:rgb(156,220,254)">key</span><span style="color:rgb(212,212,212)">: </span><span style="color:rgb(78,201,176)">CryptoKey</span><span style="color:rgb(212,212,212)">, </span><span style="color:rgb(156,220,254)">plaintext</span><span style="color:rgb(212,212,212)">: </span><span style="color:rgb(78,201,176)">Uint8Array</span><span style="color:rgb(212,212,212)">): </span><span style="color:rgb(78,201,176)">Promise</span><span style="color:rgb(212,212,212)"><</span><span style="color:rgb(78,201,176)">Encrypted</span><span style="color:rgb(212,212,212)">> {</span></div><div><span style="color:rgb(212,212,212)">  </span><span style="color:rgb(86,156,214)">const</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(156,220,254)">iv</span><span style="color:rgb(212,212,212)"> = </span><span style="color:rgb(156,220,254)">crypto</span><span style="color:rgb(212,212,212)">.</span><span style="color:rgb(220,220,170)">getRandomValues</span><span style="color:rgb(212,212,212)">(</span><span style="color:rgb(86,156,214)">new</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(78,201,176)">Uint8Array</span><span style="color:rgb(212,212,212)">(</span><span style="color:rgb(181,206,168)">12</span><span style="color:rgb(212,212,212)">));</span></div><div><span style="color:rgb(212,212,212)">  </span><span style="color:rgb(86,156,214)">const</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(156,220,254)">ciphertext</span><span style="color:rgb(212,212,212)"> = </span><span style="color:rgb(197,134,192)">await</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(156,220,254)">crypto</span><span style="color:rgb(212,212,212)">.</span><span style="color:rgb(156,220,254)">subtle</span><span style="color:rgb(212,212,212)">.</span><span style="color:rgb(220,220,170)">encrypt</span><span style="color:rgb(212,212,212)">({ </span><span style="color:rgb(156,220,254)">name</span><span style="color:rgb(156,220,254)">:</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(206,145,120)">"AES-GCM"</span><span style="color:rgb(212,212,212)">, </span><span style="color:rgb(156,220,254)">iv</span><span style="color:rgb(212,212,212)"> }, </span><span style="color:rgb(156,220,254)">key</span><span style="color:rgb(212,212,212)">, </span><span style="color:rgb(156,220,254)">plaintext</span><span style="color:rgb(212,212,212)">);</span></div><div><span style="color:rgb(212,212,212)">  </span><span style="color:rgb(197,134,192)">return</span><span style="color:rgb(212,212,212)"> { </span><span style="color:rgb(156,220,254)">iv</span><span style="color:rgb(212,212,212)">, </span><span style="color:rgb(156,220,254)">ciphertext</span><span style="color:rgb(156,220,254)">:</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(86,156,214)">new</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(78,201,176)">Uint8Array</span><span style="color:rgb(212,212,212)">(</span><span style="color:rgb(156,220,254)">ciphertext</span><span style="color:rgb(212,212,212)">) };</span></div><div><span style="color:rgb(212,212,212)">}</span></div><br><div><span style="color:rgb(197,134,192)">export</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(86,156,214)">async</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(86,156,214)">function</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(220,220,170)">sessionDecrypt</span><span style="color:rgb(212,212,212)">(</span><span style="color:rgb(156,220,254)">key</span><span style="color:rgb(212,212,212)">: </span><span style="color:rgb(78,201,176)">CryptoKey</span><span style="color:rgb(212,212,212)">, { </span><span style="color:rgb(156,220,254)">iv</span><span style="color:rgb(212,212,212)">, </span><span style="color:rgb(156,220,254)">ciphertext</span><span style="color:rgb(212,212,212)"> }: </span><span style="color:rgb(78,201,176)">Encrypted</span><span style="color:rgb(212,212,212)">): </span><span style="color:rgb(78,201,176)">Promise</span><span style="color:rgb(212,212,212)"><</span><span style="color:rgb(78,201,176)">Uint8Array</span><span style="color:rgb(212,212,212)">> {</span></div><div><span style="color:rgb(212,212,212)">  </span><span style="color:rgb(86,156,214)">const</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(156,220,254)">plaintext</span><span style="color:rgb(212,212,212)"> = </span><span style="color:rgb(197,134,192)">await</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(156,220,254)">crypto</span><span style="color:rgb(212,212,212)">.</span><span style="color:rgb(156,220,254)">subtle</span><span style="color:rgb(212,212,212)">.</span><span style="color:rgb(220,220,170)">decrypt</span><span style="color:rgb(212,212,212)">({ </span><span style="color:rgb(156,220,254)">name</span><span style="color:rgb(156,220,254)">:</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(206,145,120)">"AES-GCM"</span><span style="color:rgb(212,212,212)">, </span><span style="color:rgb(156,220,254)">iv</span><span style="color:rgb(212,212,212)"> }, </span><span style="color:rgb(156,220,254)">key</span><span style="color:rgb(212,212,212)">, </span><span style="color:rgb(156,220,254)">ciphertext</span><span style="color:rgb(212,212,212)">);</span></div><div><span style="color:rgb(212,212,212)">  </span><span style="color:rgb(197,134,192)">return</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(86,156,214)">new</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(78,201,176)">Uint8Array</span><span style="color:rgb(212,212,212)">(</span><span style="color:rgb(156,220,254)">plaintext</span><span style="color:rgb(212,212,212)">);</span></div><div><span style="color:rgb(212,212,212)">}</span></div><br></div>

</div></div>