Creating JWT signing method for AWS key in Go - go

I generated an ECC_NIST_P521 spec key, which uses the ECDSA_SHA_512 signing algorithm. I'm trying to create a jwt.SigningMethod with this in mind, but I'm not sure which values to use for the fields. This is what I have so far:
signingMethod := jwt.SigningMethodECDSA {
Name: "ECC_NIST_P521",
Hash: crypto.SHA512,
}
Specifically, I'm not sure if the name is correct and I don't know what to use for the KeySize and CurveBits fields. Any help would be appreciated.

You need to specify Hash, CurveBits and KeySize. The value of Name is ignored:
signingMethod := jwt.SigningMethodECDSA{
Name: "ECC_NIST_P521",
Hash: crypto.SHA512,
CurveBits: 521,
KeySize: 66,
}
521 bits - the size of curve field.
66 - number of bytes that fit a compact representation of a point on the curve.
Full example to sign and verify signature: https://go.dev/play/p/bEnLN2PJv4a

Related

AES GCM decrypt Firefox error only: "DOMException: The operation failed for an operation-specific reason", Chromium OK though

I followed former answers from Webcrypto AES-CBC Decrypt: Operation Error - The operation failed for an operation-specific reason and JavaScript AES encryption and decryption (Advanced Encryption Standard)
and used:
iv = crypto.getRandomValues(new Uint8Array(16))
key = window.crypto.subtle.generateKey(
{
name: "AES-GCM",
length: 256,
},
false,
["encrypt", "decrypt"]
)
to generate the key
and
Uint8ArrayEncrypted = window.crypto.subtle.encrypt(
{name: "aes-gcm", iv: iv, tagLength: 128},
key,
Uint8ArrayVar)
to encrypt and
Uint8ArrayDecrypted = window.crypto.subtle.decrypt(
{name: "aes-gcm", iv: iv, tagLength: 128},
key,
Uint8ArrayEncrypted)
to decrypt
On Chromium 83 (Ubuntu) and Firefox 88, I successfully generate the key, the iv and encrypt.
And on Chromium, it simply also decrypts without problem.Uint8ArrayDecrypted is correct ArrayBuffer.
But FF throws the error "The operation failed for an operation-specific reason" and stop there. No Uint8ArrayDecrypted returned.
I didn't use tag, like in WebCrypto API: DOMException: The provided data is too small
Reading https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/encrypt,
I don't see it uses tag.
Does Firefox need something else specific?
Why the error message is so "generic"? Which operation or specific reason?
With an error so generic, I don't know where to look.

PKCS11 ECDSA parameters in go module pkcs11

I would like to know how to pass the correct argument values for ECDSA template using go module miekg/pkcs11: this is so far what i got:
privateKeyTemplate := []*pkcs11.Attribute{
pkcs11.NewAttribute(pkcs11.CKA_TOKEN, tokenPersistent),
pkcs11.NewAttribute(pkcs11.CKA_ECDSA_PARAMS, []byte{{/*how to use secp256k1?*/}),
pkcs11.NewAttribute(pkcs11.CKA_SIGN, true),
pkcs11.NewAttribute(pkcs11.CKA_LABEL, label),
pkcs11.NewAttribute(pkcs11.CKA_SENSITIVE, true),
pkcs11.NewAttribute(pkcs11.CKA_EXTRACTABLE, true),
}
Can someone please help me with this?
thanks
EDIT:
the byte array provided by Alexander is correct, however please note that my original question was also misleading. One SHOULD NOT put the ECDSA_PARAMS in the private key template, but ONLY on the public key template.
Check this line (3189) in OpenSC project:
FILL_ATTR(privkey_templ[n_privkey_attr], CKA_EC_PARAMS, gost.param_oid.value, gost.param_oid.len);
and this one (3199):
FILL_ATTR(privkey_templ[n_privkey_attr], CKA_GOSTR3410_PARAMS, gost.param_oid.value, gost.param_oid.len);
Using my experience with GOST keys I suggest that here must be an encoded OID. In your case it can look like this:
[]byte{ 06, 04, 01, 02, 03, 04 }

iText7 PdfTextExtractor.GetTextFromPage "'StandardEncoding' is not a supported encoding name."

I have a method in our software that pulls the text from a PDF, from a scan or text generated.
I usually try the GetTextFromPage() method first. If it doesn't return text, then I move onto OCR'ing the page.
I have a particular 6 page PDF with the first three pages being a scanned document, and the last two being a form.
On this PDF I'm getting an error that I can't figure out how to resolve.
'StandardEncoding' is not a supported encoding name. For information on defining a custom encoding, see the documentation for the Encoding.RegisterProvider method.
Parameter name: name
at System.Globalization.EncodingTable.internalGetCodePageFromName(String name)
at System.Globalization.EncodingTable.GetCodePageFromName(String name)
at iText.IO.Util.IanaEncodings.GetEncodingEncoding(String name)
at iText.IO.Util.EncodingUtil.ConvertToBytes(Char[] chars, String encoding)
at iText.IO.Font.PdfEncodings.ConvertToBytes(String text, String encoding)
at iText.IO.Font.FontEncoding.FillNamedEncoding()
at iText.IO.Font.FontEncoding.CreateFontEncoding(String baseEncoding)
at iText.Kernel.Font.PdfType1Font..ctor(PdfDictionary fontDictionary)
at iText.Kernel.Font.PdfFontFactory.CreateFont(PdfDictionary fontDictionary)
at iText.Kernel.Pdf.Canvas.Parser.PdfCanvasProcessor.GetFont(PdfDictionary fontDict)
at iText.Kernel.Pdf.Canvas.Parser.PdfCanvasProcessor.SetTextFontOperator.Invoke(PdfCanvasProcessor processor, PdfLiteral operator, IList`1 operands)
at iText.Kernel.Pdf.Canvas.Parser.PdfCanvasProcessor.InvokeOperator(PdfLiteral operator, IList`1 operands)
at iText.Kernel.Pdf.Canvas.Parser.PdfCanvasProcessor.ProcessContent(Byte[] contentBytes, PdfResources resources)
at iText.Kernel.Pdf.Canvas.Parser.PdfTextExtractor.GetTextFromPage(PdfPage page, ITextExtractionStrategy strategy, IDictionary`2 additionalContentOperators)
at iText.Kernel.Pdf.Canvas.Parser.PdfTextExtractor.GetTextFromPage(PdfPage page)
at EFR.OCR.OCR.ExtractTextFromPDF(FileInfo fileInfo, Int32 StartingPage, Int32 NumberOfPages) in P:\Cloud\Dropbox\EF Recovery\OCRTest\EFR.OCR\OCR.vb:line 113
I've processed many PDFs through my code, some text, some scans, some mixed together. Some had forms... This is the first time that I've had this error.
Here's a snippet of my code...
Using reader As New iText.Kernel.Pdf.PdfReader(fileInfo.FullName)
reader.SetUnethicalReading(True)
Using sourceDoc As New iText.Kernel.Pdf.PdfDocument(reader)
If NumberOfPages = 0 Then NumberOfPages = sourceDoc.GetNumberOfPages
For i As Integer = StartingPage To StartingPage + NumberOfPages - 1
Dim pageText As String = ""
Try
pageText = iText.Kernel.Pdf.Canvas.Parser.PdfTextExtractor.GetTextFromPage(sourceDoc.GetPage(i))
Catch ex As Exception
OCRLog.Log($"Error attempting to extract text from page {i}. {ex.ToString}")
End Try
If pageText = "" Then
'extract this page
Dim results As OCRResults = ExtractTextFromPDFImagePage(fileInfo.FullName, i)
pageText = results.Text
pageItems.Add(New OCRResults.PagesClass(results.Accuracy, True, pageText))
Else
pageItems.Add(New OCRResults.PagesClass(100, False, pageText))
End If
stringBuilder.Append(pageText)
Next
Return New OCRResults(stringBuilder.ToString, pageItems)
End Using
End Using
Any ideas?
There is an error in the PDF, just as indicated by the error text "'StandardEncoding' is not a supported encoding name.".
The fonts on the page you shared use the name StandardEncoding in their Encoding entries. This is not a valid name here. According to the specification ISO 32000-1 the only valid values here are MacRomanEncoding, MacExpertEncoding, and WinAnsiEncoding, see Table 111 – Entries in a Type 1 font dictionary – and Table 114 – Entries in an encoding dictionary.
Adobe Preflight also complains about these names when checking for syntax errors:
An unexpected value is associated with the key
Key: BaseEncoding
Value: /StandardEncoding
Type: CosName
Formal Representation: Encoding
Cos ID: 38
Traversal Path: ->Pages->Kids->[0]->Resources->Font->WARSP->Encoding
An unexpected value is associated with the key
Key: Encoding
Value: /StandardEncoding
Type: CosName
Formal Representation: Font.FontType1
Cos ID: 27
Traversal Path: ->Pages->Kids->[0]->Resources->Font->Arial,Bold
An unexpected value is associated with the key
Key: BaseEncoding
Value: /StandardEncoding
Type: CosName
Formal Representation: Encoding
Cos ID: 22
Traversal Path: ->Pages->Kids->[0]->Resources->Font->Arial->Encoding
An unexpected value is associated with the key
Key: BaseEncoding
Value: /StandardEncoding
Type: CosName
Formal Representation: Encoding
Cos ID: 19
Traversal Path: ->Pages->Kids->[0]->Resources->Font->ARROW->Encoding
(Excerpt from a preflight report for your shared PDF)
In spite of StandardEncoding not being a valid name here, the PDF specification knows a "Standard Encoding", see Annex D of ISO 32000-1. Most likely your document attempts to refer to that encoding at the locations outlined above.
If you need to extract text from the document in question, therefore, you may want to follow the recommendation of the error message:
For information on defining a custom encoding, see the documentation for the Encoding.RegisterProvider method.
The Encoding class here is the one in System.Text.
To extract the text from your PDF, therefore, it should suffice to implement an EncodingProvider that for the name StandardEncoding provides an Encoding instance according to the information from the STD column of the table in Annex D.2 – Latin Character Set and Encodings – of ISO 32000-1.

How to sign cert with an arbitrary or deprecated extension

For example say I want to sign a cert with an arbitrary or deprecated extension (nsCertType for example): https://www.openssl.org/docs/manmaster/man5/x509v3_config.html
I believe I'm supposed to add the arbitrary extension as part of the certificate as per below but how / where do you discover the asn1 object identifier? I've read more documentation that I care to admit today and am still stumped.
tmpl := &x509.Certificate{
SerialNumber: big.NewInt(time.Now().Unix()*1000),
Subject: pkix.Name{CommonName: "edgeproxy", Organization: []string{"edgeproxy"}},
NotBefore: now,
NotAfter: now.Add(caMaxAge),
ExtraExtensions: []pkix.Extension{
{
Id: asn1.ObjectIdentifier{}, //what goes here
Critical: false,
[]byte("sslCA"),
},
},
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth,x509.ExtKeyUsageClientAuth,x509.ExtKeyUsageEmailProtection, x509.ExtKeyUsageTimeStamping, x509.ExtKeyUsageMicrosoftCommercialCodeSigning, x509.ExtKeyUsageMicrosoftServerGatedCrypto, x509.ExtKeyUsageNetscapeServerGatedCrypto} ,
KeyUsage: x509.KeyUsageCRLSign | x509.KeyUsageCertSign,
IsCA: true,
BasicConstraintsValid: true,
}
In python I would do this but don't know how to port this into go (which is what I'm doing at the end of the day):
OpenSSL.crypto.X509Extension(
b"nsCertType",
False,
b"sslCA"
),
Go sources at https://golang.org/src/encoding/asn1/asn1.go define:
// An ObjectIdentifier represents an ASN.1 OBJECT IDENTIFIER.
type ObjectIdentifier []int
So the object identifier (OID for short) is an array of integers. The asn1 module has methods to parse them, like parseObjectIdentifier.
This is the structure you need to put after the Id: attribute.
But now you need to find out the OID you want.
While difficult to read, OpenSSL source code can show you OIDs of many things in the X.400/X.500/X.509 worlds, or at least those known by OpenSSL.
If you go to https://github.com/openssl/openssl/blob/1aec7716c1c5fccf605a46252a46ea468e684454/crypto/objects/obj_dat.h
and searching on nsCertType you get:
{"nsCertType", "Netscape Cert Type", NID_netscape_cert_type, 9, &so[407]},
so is defined previously, and if you jump at its 407th item you see:
0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x01, /* [ 407] OBJ_netscape_cert_type */
and doing a final search on OBJ_netscape_cert_type in same file gives:
71, /* OBJ_netscape_cert_type 2 16 840 1 113730 1 1 */
which means the corresponding OID is 2.16.840.1.113730.1.1
Or you can decode the above list of integers that describe this OID (see How does ASN.1 encode an object identifier? for details).
first 0x60 is 9610 so 2*40 + 16, which means the OID starts with 2.16.
then each other one is in "base128" form: if most significant bit is 1 combine the 7 least significant bits together of all following numbers until one has 0 as most significant bit
0x86 is 100001102 so has to go with 0x48 aka 010010002 so it is in fact 000011010010002 or 84010
0x01 is less than 128 so it is itself, 1
0x86 is still 100001102 but has to be paired with both 0xF8 (111110002) and 0x42 (010000102 and we stop here since first bit is 0) so 0000110111100010000102 altogether or 11373010
and the two last 0x01 are themselves, 1.
so we do get again 2.16.840.1.113730.1.1
You can double check it at some online OID browser like here:
http://oid-info.com/cgi-bin/display?oid=2.16.840.1.113730.1.1&action=display
that gives the following description for it:
Netscape certificate type (a Rec. ITU-T X.509 v3 certificate extension
used to identify whether the certificate subject is a Secure Sockets
Layer (SSL) client, an SSL server or a Certificate Authority (CA))
You can then even browse various arcs, like the netscape one, or others, to find out other OIDs.
You also get the full ASN.1 notation:
{joint-iso-itu-t(2) country(16) us(840) organization(1) netscape(113730) cert-ext(1) cert-type(1)}

Parsing a certificate string in go

I'm using ssldump to extract the certificate in a communication. When i parse the result I obtain a string in go defined as:
var string certStr
certStr = "30 82 06 9f...."
How can I parse it to a X509 certificate?
UPDATED
I have tried to parse it directly:
certSlc := []byte(certStr)
cert,err := x509.ParseCertificates(certSlc)
But the result was:
Error:asn1: structure error: tags don't match (16 vs {class:0 tag:19 length:48 isCompound:true}) {optional:false explicit:false application:false defaultValue:<nil> tag:<nil> stringType:0 timeType:0 set:false omitEmpty:false}
Should I do another kind of conversion? maybe is the string incomplete or has got wrong type of cert?
I found the error. The problem was in the source.
As I was explaining, my cert string was "30 82 06 09...". This source must be decoded with:
hex.DecodeString(certStr)
The problem is that hex decoding doesn't work with this format. The error I obtained was:
encoding/hex: invalid byte: U+0020 ' '
So, removing whitespaces and carriage returns in the original string is the solution to make it work.
After decoding in a byte slice the X509 certificate can be created with no problem.

Resources