Last active
September 24, 2015 07:16
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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