<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Jun 11, 2020, at 6:39 PM, Levente Uzonyi <<a href="mailto:leves@caesar.elte.hu" class="">leves@caesar.elte.hu</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="Singleton"><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">It is useful for SSO.  But for automated workflows, where human intervention is undesired, there is another type of OAuth2 which may be called "server to server" or apparently "two-legged OAuth":<br class=""><a href="https://developers.google.com/identity/protocols/oauth2/service-account" class="">https://developers.google.com/identity/protocols/oauth2/service-account</a><br class="">I tried and failed to implement this last year.  Where I failed was in computing the JSON Web Signature (JWS).  I could generate JWTs successfully*, but JWSs for Google require "SHA256withRSA (also known as<br class="">RSASSA-PKCS1-V1_5-SIGN with the SHA-256 hash function)" which requires one very specific algorithm missing from SqueakSSL and which I simply could not engineer on my own at the time (or perhaps ever — I might just not be<br class="">smart enough ;) ).  I was able to get as far as crafting the JSON in Squeak and then signing using Python's implementation of the algorithm and it would work.<br class="">If we could get server-to-server OAuth2 using WebClient, that would also allow us to, say, connect to Google Drive directly from Squeak, or be a client of Google Cloud Platform / Compute Engine, etc.  I think that would be<br class="">very cool.<br class="">Sadly, I seem to recall this type of OAuth (and thus this algorithm) would also be necessary for GitHub/GitLab.<br class=""></blockquote><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">The Cryptography package seems to have this stuff implemented, though I haven't verified the results. Here's how to use it:</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">Let's say privateKey is an RSAPrivateKey with your private key (See class side methods and RSAPrivateKeyFileReader how to initialize it) and message is your serialized json to sign. Then</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><span class="Apple-tab-span" style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: pre; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;">        </span><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">privateKey v15SignMessageHash: (HashFunction newSHA256 digestInfoAsn1DerEncodingFromMessage: message)</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">should return the signature.</span></div></div></blockquote><br class=""></div><div>Thank you Levente.  When I mentioned algorithms I was hoping you might respond.  :) </div><div><br class=""></div><div>I found my old JWT code from last year on GitHub:  <a href="https://github.com/tcj/beaufort" class="">https://github.com/tcj/beaufort</a>      (Oh no, it contains an old email address of mine in one of its tests...)</div><div><br class=""></div><div>I loaded Cryptography into an image so I could run my tests again, and noticed that the Cryptography package has seen a lot of work this year.  Thanks for that.</div><div><br class=""></div><div>So:  the tests I wrote last year (with a small change) pass now.  This could be very good news and may be worth further investigation.  Thank you again!  I will update my tests (& remove my old email address...?) and upload a new version of this package.</div><div><br class=""></div><div>I am reminded that the issue I'd encountered last year was that HS256 could work, but RS256 could not.  Now, unit tests are passing for both.  (My BfJWTRFCTest>>#testConversion is not passing so I'll need to look into that.)</div><div><br class=""></div><div>Here is the gist of my JWT signing code:</div><div><br class=""></div><div><div>BfJWT>>#signedWith: aKey</div><div><span class="Apple-tab-span" style="white-space:pre">     </span>| headerAndClaims |</div><div><span class="Apple-tab-span" style="white-space:pre">  </span>self secret: aKey.</div><div><span class="Apple-tab-span" style="white-space:pre">   </span>headerAndClaims := self headerAndClaims.</div><div><span class="Apple-tab-span" style="white-space:pre">     </span>^ '{1}.{2}' format: { headerAndClaims . self signatureFrom: headerAndClaims }</div><div><br class=""></div><div>... #signatureFrom: is implemented differently for HS256 versus RS256 subclasses of BfJWT.  My RS256 encoding was like this:</div><div><br class=""></div><div><div>BfRS256 signatureFrom: aString</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>| signedMessage hashed privateKey |</div><div><span class="Apple-tab-span" style="white-space:pre">  </span>privateKey := (Pkcs12PrivateKeyFileReader fromFile: 'timj-project-mar-2019-a94d67a8d0c8.p12') asPrivateKey.</div><div><span class="Apple-tab-span" style="white-space:pre">  </span>signedMessage := privateKey signMessage: aString.</div><div><span class="Apple-tab-span" style="white-space:pre">    </span>hashed := SHA256 new hashStream: signedMessage readStream.</div><div><span class="Apple-tab-span" style="white-space:pre">   </span>^ hashed base64UrlEncoded</div></div></div><div><br class=""></div><div>A year ago, I could have described how & why it wasn't working... but that information has left my brain now.</div><div><br class=""></div><div>For what it's worth, Norbert Hartl's JSONWebToken also lacks support for this RS256 encoding format.</div><div><br class=""></div><div><a href="https://github.com/noha/JSONWebToken/commit/4a4d20eaa6e84e2676a577f74bc6e24c1ead0047" class="">https://github.com/noha/JSONWebToken/commit/4a4d20eaa6e84e2676a577f74bc6e24c1ead0047</a></div><div><br class=""></div><div>It seems to be a common issue around the internet that people find RS256 very difficult.</div><div><br class=""></div><div>Thanks again,</div><div>Tim</div><div><br class=""></div><div><br class=""></div><br class=""></body></html>