Skip to content

Instantly share code, notes, and snippets.

@hillar
Last active September 24, 2015 07:16
Show Gist options
  • Save hillar/9af4b7835447d29ed971 to your computer and use it in GitHub Desktop.
Save hillar/9af4b7835447d29ed971 to your computer and use it in GitHub Desktop.
failed to parse certificate: x509: RSA modulus is not a positive number or not minimal
package main
import "fmt"
import "encoding/pem"
import "encoding/asn1"
import "math/big"
import "time"
import "os"
import "io/ioutil"
type certificate struct {
Raw asn1.RawContent
TBSCertificate tbsCertificate
SignatureAlgorithm AlgorithmIdentifier
SignatureValue asn1.BitString
}
type tbsCertificate struct {
Raw asn1.RawContent
Version int `asn1:"optional,explicit,default:1,tag:0"`
SerialNumber *big.Int
SignatureAlgorithm AlgorithmIdentifier
Issuer asn1.RawValue
Validity validity
Subject asn1.RawValue
PublicKeyInfo publicKeyInfo
UniqueId asn1.BitString `asn1:"optional,tag:1"`
SubjectUniqueId asn1.BitString `asn1:"optional,tag:2"`
Extensions []Extension `asn1:"optional,explicit,tag:3"`
}
type AlgorithmIdentifier struct {
Algorithm asn1.ObjectIdentifier
Parameters asn1.RawValue `asn1:"optional"`
}
type validity struct {
NotBefore, NotAfter time.Time
}
type publicKeyInfo struct {
Raw asn1.RawContent
Algorithm AlgorithmIdentifier
PublicKey asn1.BitString
}
type Extension struct {
Id asn1.ObjectIdentifier
Critical bool `asn1:"optional"`
Value []byte
}
type rsaPublicKey struct {
N *big.Int
E int
}
func test_BN_R_BAD_ENCODING(testPEM string) {
block, _ := pem.Decode([]byte(testPEM))
if block == nil {
fmt.Printf("failed to parse PEM\n")
}
var cert certificate
_, err := asn1.Unmarshal(block.Bytes, &cert)
if err != nil {
fmt.Printf("failed to parse cert: %#v \n", err)
}
//SerialNumber := cert.TBSCertificate.SerialNumber
NotBefore := cert.TBSCertificate.Validity.NotBefore.Local()
isNegative := false
isZeroPaded := false
isBroken := false
//fmt.Printf("NotBefore in cert: %s \n", cert.TBSCertificate.Validity.NotBefore.Local())
asn1Data := cert.TBSCertificate.PublicKeyInfo.PublicKey.Bytes
p := new(rsaPublicKey)
_, rerr := asn1.Unmarshal(asn1Data, p)
if rerr != nil {
fmt.Printf("failed to unmarshal public key: %#v \n", rerr)
}
if p.N.Sign() <= 0 {
//fmt.Printf("x509: RSA modulus is not a positive number: %#v \n",asn1Data[8:])
isNegative = true
}
// see https://github.com/beurdouche/boringssl/blob/d7fe75ca5f167944e5c8d46b1058d8bd861159e6/crypto/bn/bn_asn1.c#L54
// INTEGERs must be minimal.
if asn1Data[8] == 0x0 {
//public key modulus is padded with 0x0
isZeroPaded = true
}
x := asn1Data[9]
//Bits, least to most significant:
tmp := make([]byte, 8)
for i := uint(0); i < 8; i++ {
tmp[i] = (x & (1 << i) >> i)
}
if isNegative || (isZeroPaded && tmp[7]!=1){
isBroken = true
}
fmt.Printf("'%s', %v, %v, %v, %v, %v,'%v', '%v'\n", NotBefore, isBroken, isNegative, isZeroPaded, tmp[7],len(asn1Data),asn1Data[9],tmp)
}
const badCERT_not_minimal = `
-----BEGIN CERTIFICATE-----
MIIFPzCCBCegAwIBAgIQNdX81Pa9AFJTajNjz/8w0zANBgkqhkiG9w0BAQUFADBs
MQswCQYDVQQGEwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1
czEfMB0GA1UEAwwWVEVTVCBvZiBFU1RFSUQtU0sgMjAxMTEYMBYGCSqGSIb3DQEJ
ARYJcGtpQHNrLmVlMB4XDTE0MDUwNzEzMjEzOVoXDTE5MDQwNzIwNTk1OVowgZcx
CzAJBgNVBAYTAkVFMQ8wDQYDVQQKDAZFU1RFSUQxFzAVBgNVBAsMDmF1dGhlbnRp
Y2F0aW9uMSQwIgYDVQQDDBvFvUFJS09WU0tJLElHT1IsMzcxMDEwMTAwMjExEzAR
BgNVBAQMCsW9QUlLT1ZTS0kxDTALBgNVBCoMBElHT1IxFDASBgNVBAUTCzM3MTAx
MDEwMDIxMIIBIzANBgkqhkiG9w0BAQEFAAOCARAAMIIBCwKCAQEAXYZkxZII5v+R
VySl/qexjElVOqwuLmNYeVos1QSxHu6g5sZX086gBm8Y/Qff4HyiuJuWyrP8tyvn
k65LpnSjQmjzuFG3fYo1WubGKwBPq/j11xpj7vjmRFjRL+oeObn07Zd/LUyK+HRO
EQW70ZMHV6ufZBE6AWevNCnWRxRgKYq7o/kGUqYvKXyWyg2ShoXyghoYSeCCq9g5
tNSfr0R9yezVLCe7wOhR02g+1BKbSwHeglTMLOsB5ZbaOZjPJRS80m5q0JH4Tq76
ivtPwKVbsY8BJkHcoq+pFEY0llBXy04ooLyrIxc2wWpgoeEcUPUBHD1IvW4msTz9
JRVGiZ992wIETJPlaaOCAa4wggGqMAkGA1UdEwQCMAAwDgYDVR0PAQH/BAQDAgSw
MIGZBgNVHSAEgZEwgY4wgYsGCisGAQQBzh8DAQEwfTBYBggrBgEFBQcCAjBMHkoA
QQBpAG4AdQBsAHQAIAB0AGUAcwB0AGkAbQBpAHMAZQBrAHMALgAgAE8AbgBsAHkA
IABmAG8AcgAgAHQAZQBzAHQAaQBuAGcALjAhBggrBgEFBQcCARYVaHR0cDovL3d3
dy5zay5lZS9jcHMvMCQGA1UdEQQdMBuBGWlnb3IuemFpa292c2tpLjNAZWVzdGku
ZWUwHQYDVR0OBBYEFHxuNE269r7Wi54NMxrTsDlkLjw3MCAGA1UdJQEB/wQWMBQG
CCsGAQUFBwMCBggrBgEFBQcDBDAiBggrBgEFBQcBAwQWMBQwCAYGBACORgEBMAgG
BgQAjkYBBDAfBgNVHSMEGDAWgBRBtv7FsbG0UxOM+vpi0DRtbSI0CjBFBgNVHR8E
PjA8MDqgOKA2hjRodHRwOi8vd3d3LnNrLmVlL3JlcG9zaXRvcnkvY3Jscy90ZXN0
X2VzdGVpZDIwMTEuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQBzCEQos6/csx3YTb/n
OixfbDMplZ0Vj85USb2ecvlmoQh7eVlzlge+YYLSxOl+pnqQBKn2ANERSVawxyaT
U9z5hviGaBo6b61l3jPraUWwdLygQWHawmig5g0+jfMfk91aqeuy9e/JCooDqXJQ
SbqG8BohRwN1bkrwO44Iltn090hGQpmZNBR3T9xDLElr11wvxIbMyzunzjJCiTe1
Cnr8On4zPTjFuE+ix53c3lJBT4vHIGpCvR5U3qoSPLLT31x7LYbBOG3Y4eLd9gwX
F9freO7PaoA97JmBKmc6J8/3Kpdw7DJpgyqvm0PCu8Yp0URytvfnxXdlCzM+yYTO
JwD0
-----END CERTIFICATE-----`
const badCERT_negative_modulus = `
-----BEGIN CERTIFICATE-----
MIIFRDCCBCygAwIBAgIQVG1g+alwvKFUQOVgh5UdPjANBgkqhkiG9w0BAQUFADBs
MQswCQYDVQQGEwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1
czEfMB0GA1UEAwwWVEVTVCBvZiBFU1RFSUQtU0sgMjAxMTEYMBYGCSqGSIb3DQEJ
ARYJcGtpQHNrLmVlMB4XDTE0MTAxNzA5NDYwOFoXDTE5MDQwNzIwNTk1OVowgZsx
CzAJBgNVBAYTAkVFMQ8wDQYDVQQKDAZFU1RFSUQxFzAVBgNVBAsMDmF1dGhlbnRp
Y2F0aW9uMSYwJAYDVQQDDB1Nw4ROTklLLE1BUkktTElJUyw0NzEwMTAxMDAzMzEQ
MA4GA1UEBAwHTcOETk5JSzESMBAGA1UEKgwJTUFSSS1MSUlTMRQwEgYDVQQFEws0
NzEwMTAxMDAzMzCCASEwDQYJKoZIhvcNAQEBBQADggEOADCCAQkCggEAlqYunE5q
w8zNj3DDVb9enNTzF8OXcK7fElwVgAPvKxidastSIsGBuH5h6A95JA+CcCROKSAF
VOvUqWVZtjx1lS9M9p3Rr18UFOcl6qVHXcY+KI3cVIcqfBDpxnYt53nYDruprLUY
mNZHbgZwv56CJZVO/XDXc0UuwR96mp1gwB9nBipOhz8ZiGlkTZ919dMaQT01F7bR
RA0li+eUObB8rz5q+o2QIQ+KQ5Q3fCoVTKD6qS8hpm+OL4m8uzP4MfzfzWiavHUG
lfE978p2J9K6jg4cQ9dwucYVytVNh7nRrt5pcwAql1FLMAHChdAFzC7ox0LnlFHj
9Rk13FeW59m0SQIDAQABo4IBsTCCAa0wCQYDVR0TBAIwADAOBgNVHQ8BAf8EBAMC
BLAwgZkGA1UdIASBkTCBjjCBiwYKKwYBBAHOHwMBATB9MFgGCCsGAQUFBwICMEwe
SgBBAGkAbgB1AGwAdAAgAHQAZQBzAHQAaQBtAGkAcwBlAGsAcwAuACAATwBuAGwA
eQAgAGYAbwByACAAdABlAHMAdABpAG4AZwAuMCEGCCsGAQUFBwIBFhVodHRwOi8v
d3d3LnNrLmVlL2Nwcy8wJwYDVR0RBCAwHoEcbWFyaS1saWlzLm1hbm5pay4yM0Bl
ZXN0aS5lZTAdBgNVHQ4EFgQUXqHPC2v2/rL6YK/2/c4Uec4L6icwIAYDVR0lAQH/
BBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMCIGCCsGAQUFBwEDBBYwFDAIBgYEAI5G
AQEwCAYGBACORgEEMB8GA1UdIwQYMBaAFEG2/sWxsbRTE4z6+mLQNG1tIjQKMEUG
A1UdHwQ+MDwwOqA4oDaGNGh0dHA6Ly93d3cuc2suZWUvcmVwb3NpdG9yeS9jcmxz
L3Rlc3RfZXN0ZWlkMjAxMS5jcmwwDQYJKoZIhvcNAQEFBQADggEBAK2WBvRIiqGa
k4kVfuzgx+vVQ2Nk+p57scKR3De5ol66A17WuxDulRXaWICEV8Bqrrh0iywcIC/i
cGOr32nJEVNI/VrqbOqhU+w8pvhWjRZkQWaTGoYzIX8D0KxiLMwJ2ZAnPZ5T5nsG
jV+po3REl2Z10ktTxbnvtmlie/cOmdaPkKqu81DKYNDOQg3subR74uZH6dBNabuE
e2a5hjWDFzJteOSkY39eutyr7pWyTCbj5VqFwQRRWrnNUbM3FI2TBK2XzB5WlN2d
64nXjyvjk/j1sP6FoBtZcN406niC6eElkk3NWMU9WA5GWh1TFDvNd1vkvDdIG8RZ
gq44ArYd5fo=
-----END CERTIFICATE-----`
func main(){
if len(os.Args) > 1 {
dat, err := ioutil.ReadFile(os.Args[1])
if err == nil {
test_BN_R_BAD_ENCODING(string(dat))
} else {
fmt.Println("error reading file %s %#v",os.Args[1], err)
}
} else {
fmt.Println("# Hello, BN_R_BAD_ENCODING ;(")
fmt.Println("# NotBefore, isBroken, isNegative, isZeroPaded, signbit, pubkey.len, modulus.0, modulus.1")
test_BN_R_BAD_ENCODING(badCERT_not_minimal)
test_BN_R_BAD_ENCODING(badCERT_negative_modulus)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment