Version 0 of Signing a JWT header for Google OAuth2

Updated 2013-10-26 04:39:06 by BMA

According to the documentation at Using OAuth 2.0 for Server to Server Applications

The signing algorithm in the JWT header must be used when computing the signature. 
The only signing algorithm supported by the Google OAuth 2.0 Authorization Server is 
RSA using SHA-256 hashing algorithm. This is expressed as ‘RS256’ in the ‘alg’ field in the JWT header.

Sign the UTF-8 representation of the input using SHA256withRSA 
(also known as RSASSA-PKCS1-V1_5-SIGN with the SHA-256 hash function) with the private key 
obtained from the Google Cloud Console. The output will be a byte array.

What is there in the tcl space that is equivalent to SHA256withRSA (also known as RSASSA-PKCS1-V1_5-SIGN with the SHA-256 hash function)? I was thinking that the sha256 package would do the trick, but now I'm not so sure. Reason is that I took the signature block given on the developers.google.com page and did a ::base64::decode. This gave me a string of assorted low and high ascii, which is not what I'm getting with a ::sha2::hmac

The goal is to be able to set up an OAuth2 connection to Google Analytics. I've already been to the Google Cloud Console to set up the account, and get the various keys. The code I'm using is below. I'm still at the point where you generate the header. I haven't got to the HTTP stuff yet.

package require json
package require sha256
package require base64

set h [open "client_secret.json" r]
set d [read $h]
close $h

set mydd [dict create {*}[lindex [::json::json2dict $d] 1]]

set header [string map {\n "" "=" ""} [::base64::encode "{\"alg\":\"RS256\",\"typ\":\"JWT\"}"]]
set claims [string map {\n "" "=" ""} [::base64::encode "{\
\"iss\":\"[dict get $mydd client_email]\",\
\"scope\":\"https://www.googleapis.com/auth/analytics.readonly\",\
\"aud\":\"https://accounts.google.com/o/oauth2/token\",\
\"exp\":[expr [clock seconds] + 3600],\
\"iat\":[clock seconds]\
}"]]

set signature "$header.$claims"

set h [open "privatekey.p12" r]
fconfigure $h -translation binary
set d [read $h]
close $h

set sig [string map {\n "" "=" ""} [::base64::encode [::sha2::hmac $d $signature]]]
set final "$signature.$sig"

puts $final