I’m trying to connect to Xero via their private application system.
Full disclosure here this is my first time working certificates. I’ve copied bits and pieces from the documentation and examples so I’m fully prepared that I’ve totally stuffed this up.
I’ve tested the signature with C# that works fine. So I has to be something in the Clarion code.
I’ve loaded a pfx file into my local store and is supposed to sign and hash a string with my private key USING RSA-SHA1.
Since I’ve got Capesoft Cryponite and NetTalk I’m trying to use those.
Here’s the code. I’m unsure if this is loading the private key but none of the first parts are generating any errors so I believe I’m good there. You can seem to specify to use RSA when signing the code but the verify does show my email address and “348” which I’m unsure about.
RESPONSE from XERO: oauth_problem=signature_method_rejected&oauth_problem_advice=Private%20applications%20must%20use%20the%20RSA-SHA1%20signature%20method
Which to me looks like the string was not properly signed and hashed.
If Crypto.GetContainer('myETW', true) <> Crypto:OK
Stop('Get Container Failed')
End
storeName = 'MY'
CertificateName = 'Bertus Viljoen'
LOC:ConsumerKey.SetValue('PZI118TAMBCNHT7LNKINNUT7N85N5F')
Result = Crypto:NotOK
Store = Crypto.CertOpenSystemStore (StoreName)
If Store
CertContext = Crypto.CertFind (Store, clip(CertificateName))
If CertContext
Provider = Crypto.CertGetPrivateKey(CertContext, FreeKey)
If Provider
Crypto.hProvider = Provider
Result = Crypto.GetUserKey()
End
End
End
TimeStamp = (((Today()-61730)*86400)+(CLOCK()/100-36000))
! TimeStamp = 1559906676
! STOP(TimeStamp)
LOC:Request.SetValue('oauth_consumer_key='&LOC:ConsumerKey.GetValue()&|
'&oauth_nonce=471weirpow-0e06-4e0b-a97b-379878976671'&|
'&oauth_signature_method=RSA-SHA1'&|
'&oauth_timestamp='&TimeStamp&|
'&oauth_token='&LOC:ConsumerKey.GetValue()&|
'&oauth_version=1.0')
LOC:AuthStr.SetValue('GET&https://api.xero.com/api.xro/2.0/Organisation&'&LOC:Request.GetValue())
LOC:AuthStr.UrlEncode()
! Stop(LOC:AuthStr.GetValue())
If Crypto.SignMessage(LOC:AuthStr,cs:CALG_SHA1,CertificateName,LOC:Signature,Crypto:EncBase64,True,True) <> Crypto:OK
Stop('Sign message Failed')
Else
If Crypto.VerifySignature(LOC:AuthStr,LOC:Signature,Crypto:EncBase64,CertificateName,CertInfo,,Verified) = Crypto:NotOk
Case Verified
Of Crypto:NoProvider
Stop('If the message Crypto:NoProvider is not found')
Of Crypto:NTE_BAD_SIGNATURE
Stop('If the message Crypto:NTE_BAD_SIGNATURE is not found')
Of Crypto:NTE_BAD_ALGID
Stop('If the message Crypto:NTE_BAD_ALGID is not found')
Of Crypto:CRYPT_E_NO_SIGNER
Stop('If the message Crypto:CRYPT_E_NO_SIGNER is not found')
Of Crypto:CRYPT_E_UNEXPECTED_MSG_TYPE
Stop('If the message Crypto:CRYPT_E_UNEXPECTED_MSG_TYPE is not found')
Of Crypto:E_INVALIDARG
Stop('If the message Crypto:E_INVALIDARG is not found')
Of Crypto:CERTNOTTRUSTED
Stop('If the certificate is marked as untrusted on the system (this is not implemented because it is application-specific) ')
Of Crypto:CERTEXPIRED
Stop('If the certificate''s time validity check fails ')
Of Crypto:CERTREVOKED
Stop('If the certificate is in the issuer''s CRL ')
Of Crypto:ISSUERSIGFAILED
Stop('If the issuer signature on the certificate fails ')
Of Crypto:ISSUERCERTNOTFOUND
Stop('If the issuer certificate not found on local machine ')
Of Crypto:MSG_CERTNOTFOUND
Stop('If the message certificate is not found')
Of Crypto:MSG_ALTERED
Stop('If the message Crypto:MSG_ALTERED is not found')
Else
Stop(CLIP(CertificateName)&'<13,10>'&CLIP(Verified)&'<13.10>')
End
End
End
! Stop(LOC:Signature.GetValue())
! Crypto.EncryptString(LOC:AuthStr,'',,cs:PROV_RSA_FULL)
! Crypto.MakeHash(LOC:AuthStr,cs:CALG_SHA1)
! LOC:AuthStr.Base64Encode()
XeroClient.SetAllHeadersDefault()
XeroClient.HeaderOnly = False
XeroClient.AcceptEncoding = ''!'gzip,deflate'
XeroClient.CanUseProxy = 0
XeroClient.Authorization = 'Oauth oauth_consumer_key='&LOC:ConsumerKey.GetValue()&', oauth_nonce=471weirpow-0e06-4e0b-a97b-379878976671, oauth_signature='&Clip(LOC:Signature.GetValue())&|
', oauth_signature_method=RSA-SHA1, oauth_timestamp='&TimeStamp&',oauth_token='&LOC:ConsumerKey.GetValue()&',oauth_version=1.0'
XeroClient.ContentType = 'application/json; charset=utf-8'
XeroClient.SSLMethod = NET:SSLMethodTLSv1_2
XeroClient.GET('https://api.xero.com/api.xro/2.0/organisation','')