I would like to be able to unmarshal a large integer from a DER file using the encoding/asn1 package, but it looks like it only works for a SEQUENCE of integers.
For example, this does not work, which is strange because the marshaling of the Big Int works well ( https://play.golang.org/p/Wkj0jAA6bpq ) :
package main
import (
"encoding/asn1"
"fmt"
"math/big"
)
func main() {
r, _ := new(big.Int).SetString("481B6A0913BD8024CA5D22F014F3", 16);
encoding, _ := asn1.Marshal(r)
fmt.Printf("% X\n", encoding) // Displayed as an integer: 02 0E 48 1B 6A 09 13 BD 80 24 CA 5D 22 F0 14 F3
var t big.Int
_, err := asn1.Unmarshal(encoding, &t)
if err != nil {
fmt.Println("Erreur unmarshalling -", err) // asn1: structure error: tags don't match
}
fmt.Println(t.String())
}
It looks like I can unmarshall a large integer only if it's part of a SEQUENCE like in this example : https://play.golang.org/p/J93afvbk41L
package main
import (
"encoding/asn1"
"fmt"
"math/big"
)
type TestBigInt struct { // From encoding/asn1/asn1_test.go
X *big.Int
}
func main() {
r, _ := new(big.Int).SetString("481B6A0913BD8024CA5D22F014F3", 16);
encoding, _ := asn1.Marshal(TestBigInt{r})
fmt.Printf("% X\n", encoding) // Displayed as a sequence of an integer: 30 10 02 0E 48 1B 6A 09 13 BD 80 24 CA 5D 22 F0 14 F3
var t TestBigInt
_, err := asn1.Unmarshal(encoding, &t)
if err != nil {
fmt.Println("Erreur unmarshalling -", err)
}
fmt.Println(t.X.String())
}
However, it works well for 32 bits of 64 bits integer like in this example : https://play.golang.org/p/vcIgWrI-sk-
package main
import (
"encoding/asn1"
"fmt"
)
func main() {
r := 12234
encoding, _ := asn1.Marshal(r)
fmt.Printf("% X\n", encoding)
var t int
_, err := asn1.Unmarshal(encoding, &t)
if err != nil {
fmt.Println("Erreur unmarshalling -", err)
}
fmt.Println(t)
}
Is this a known limitation of the encoding/asn1 package ? Any known solution to unmarshal a large integer outside a SEQUENCE ?
The documentation states that:
An ASN.1 INTEGER can be written to an int, int32, int64, or *big.Int (from the math/big package).
Note that the fourth option is a *big.Int
, not a big.Int
. You can't see it because of the auto type deduction, but the former is actually the same type as r
in your first example, and more clearly the type of X
in your second example, too.
If you change your variable to a pointer, then it should work. For example, modifying your first example:
package main
import (
"encoding/asn1"
"fmt"
"math/big"
)
func main() {
r, _ := new(big.Int).SetString("481B6A0913BD8024CA5D22F014F3", 16);
encoding, _ := asn1.Marshal(r)
fmt.Printf("% X\n", encoding)
var t *big.Int // <---- changed type
_, err := asn1.Unmarshal(encoding, &t)
if err != nil {
fmt.Println("Erreur unmarshalling -", err)
}
fmt.Println(t.String())
}
yields:
paul@horus:asn1int$ ./asn1int
02 0E 48 1B 6A 09 13 BD 80 24 CA 5D 22 F0 14 F3
1462505468235399478280266926003443
paul@horus:asn1int$
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.