// PublicPEM returns the PEM-encoded public key func PublicPEM(key *ecdsa.PrivateKey) ([]byte, error) { pubBytes, err := x509.MarshalPKIXPublicKey(key.Public()) if err != nil { return nil, err } pubPEM := pem.EncodeToMemory(&pem.Block{ Type: "PUBLIC KEY", Bytes: pubBytes, }) return pubPEM, nil }
func newCert(key *ecdsa.PrivateKey) (cert *x509.Certificate, err error) { template := &x509.Certificate{ SerialNumber: new(big.Int).SetInt64(time.Now().UnixNano()), Subject: pkix.Name{ CommonName: "nutcracker", }, NotBefore: time.Now().Add(-5 * time.Minute).UTC(), NotAfter: time.Now().AddDate(1, 0, 0).UTC(), KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, SignatureAlgorithm: x509.ECDSAWithSHA256, } derBytes, err := x509.CreateCertificate(rand.Reader, template, template, key.Public(), key) if err != nil { return } return x509.ParseCertificate(derBytes) }
// GenerateCertificate generates an X509 Certificate from a template, given a GUN func (ucs *UnlockedCryptoService) GenerateCertificate(gun string) (*x509.Certificate, error) { algorithm := ucs.PrivKey.Algorithm() var publicKey crypto.PublicKey var privateKey crypto.PrivateKey var err error switch algorithm { case data.RSAKey: var rsaPrivateKey *rsa.PrivateKey rsaPrivateKey, err = x509.ParsePKCS1PrivateKey(ucs.PrivKey.Private()) privateKey = rsaPrivateKey publicKey = rsaPrivateKey.Public() case data.ECDSAKey: var ecdsaPrivateKey *ecdsa.PrivateKey ecdsaPrivateKey, err = x509.ParseECPrivateKey(ucs.PrivKey.Private()) privateKey = ecdsaPrivateKey publicKey = ecdsaPrivateKey.Public() default: return nil, fmt.Errorf("only RSA or ECDSA keys are currently supported. Found: %s", algorithm) } if err != nil { return nil, fmt.Errorf("failed to parse root key: %s (%v)", gun, err) } template, err := trustmanager.NewCertificate(gun) if err != nil { return nil, fmt.Errorf("failed to create the certificate template for: %s (%v)", gun, err) } derBytes, err := x509.CreateCertificate(rand.Reader, template, template, publicKey, privateKey) if err != nil { return nil, fmt.Errorf("failed to create the certificate for: %s (%v)", gun, err) } // Encode the new certificate into PEM cert, err := x509.ParseCertificate(derBytes) if err != nil { return nil, fmt.Errorf("failed to parse the certificate for key: %s (%v)", gun, err) } return cert, nil }
// GenSignature - Debugging function to sign a message func GenSignature(w http.ResponseWriter, r *http.Request) { // Returns a Public / Private Key Pair // Uses eliptic curve cryptography // Generate a public / private key pair privatekey := new(ecdsa.PrivateKey) // Generate an elliptic curve using NIST P-224 ecurve := elliptic.P224() privatekey, err := ecdsa.GenerateKey(ecurve, rand.Reader) if err != nil { panic(err) } // Marshal the JSON privkey, _ := json.Marshal(privatekey) publikey, _ := json.Marshal(privatekey.Public()) // Get the public key var pubkey ecdsa.PublicKey pubkey = privatekey.PublicKey // Try signing a message message := []byte("This is a test") sig1, sig2, err := ecdsa.Sign(rand.Reader, privatekey, message) // Try verifying the signature result := ecdsa.Verify(&pubkey, message, sig1, sig2) if result != true { panic("Unable to verify signature") } fmt.Fprintln(w, "Marshaled Private Key:", string(privkey)) fmt.Fprintln(w, "Marshaled Public Key:", string(publikey)) fmt.Fprintln(w, "Curve: ", pubkey.Curve) fmt.Fprintf(w, "Curve: Private: %#v\nPublic: %#v\n\nSignature:\n%v\n%v\n\nVerified: %v", privatekey, pubkey, sig1, sig2, result) }