Skip to content

Instantly share code, notes, and snippets.

@tam7t
Created April 26, 2015 22:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tam7t/24c6eeecddf38a6845e5 to your computer and use it in GitHub Desktop.
Save tam7t/24c6eeecddf38a6845e5 to your computer and use it in GitHub Desktop.
Certificate manipulation tool
/* pemedit - certificate manipulation tool
* by @tam7t
*
* Usage:
* > go build pemedit.go
* > ./pemedit.go -in=server.pem -cn=google.com > cert.new.pem
* > openssl x509 -in cert.new.pem -text -noout
*/
package main
import (
"crypto/x509/pkix"
"encoding/asn1"
"encoding/pem"
"flag"
"fmt"
"io/ioutil"
"math/big"
"time"
)
// Taken from x509.go augmented with asn1_test.go
// These structures reflect the ASN.1 structure of X.509 certificates.:
type certificate struct {
// Raw asn1.RawContent
TBSCertificate tbsCertificate
SignatureAlgorithm pkix.AlgorithmIdentifier
SignatureValue asn1.BitString
}
type tbsCertificate struct {
// Raw asn1.RawContent
Version int `asn1:"optional,explicit,default:1,tag:0"`
SerialNumber *big.Int
SignatureAlgorithm pkix.AlgorithmIdentifier
Issuer RDNSequence
Validity validity
Subject RDNSequence
PublicKey publicKeyInfo
UniqueId asn1.BitString `asn1:"optional,tag:1"`
SubjectUniqueId asn1.BitString `asn1:"optional,tag:2"`
Extensions []pkix.Extension `asn1:"optional,explicit,tag:3"`
}
type RDNSequence []RelativeDistinguishedNameSET
type RelativeDistinguishedNameSET []AttributeTypeAndValue
type AttributeTypeAndValue struct {
Type asn1.ObjectIdentifier
Value interface{}
}
type dsaAlgorithmParameters struct {
P, Q, G *big.Int
}
type dsaSignature struct {
R, S *big.Int
}
type ecdsaSignature dsaSignature
type validity struct {
NotBefore, NotAfter time.Time
}
type publicKeyInfo struct {
Raw asn1.RawContent
Algorithm pkix.AlgorithmIdentifier
PublicKey asn1.BitString
}
func main() {
var inCert, newCn string
flag.StringVar(&inCert, "in", "cert.pem", "PEM encoded public certificate")
flag.StringVar(&newCn, "cn", "example.com", "The new Common Name")
flag.Parse()
// load cert
data, _ := ioutil.ReadFile(inCert)
// decode PEM
blk, data := pem.Decode(data)
// PEM block data is ASN1 encoded certificate
var cert certificate
asn1.Unmarshal(blk.Bytes, &cert)
// set new CN
cert.TBSCertificate.Subject[5][0].Value = newCn
// re-encode structs back to PEM
newCert, _ := asn1.Marshal(cert)
blk.Bytes = newCert
newCertPem := pem.EncodeToMemory(blk)
// output cert
fmt.Print(string(newCertPem))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment