// ParsePEMPrivateKey returns a data.PrivateKey from a PEM encoded private key. It // only supports RSA (PKCS#1) and attempts to decrypt using the passphrase, if encrypted. func ParsePEMPrivateKey(pemBytes []byte, passphrase string) (*data.PrivateKey, error) { block, _ := pem.Decode(pemBytes) if block == nil { return nil, errors.New("no valid private key found") } switch block.Type { case "RSA PRIVATE KEY": var privKeyBytes []byte var err error if x509.IsEncryptedPEMBlock(block) { privKeyBytes, err = x509.DecryptPEMBlock(block, []byte(passphrase)) if err != nil { return nil, errors.New("could not decrypt private key") } } else { privKeyBytes = block.Bytes } rsaPrivKey, err := x509.ParsePKCS1PrivateKey(privKeyBytes) if err != nil { return nil, fmt.Errorf("could not parse DER encoded key: %v", err) } tufRSAPrivateKey, err := RSAToPrivateKey(rsaPrivKey, data.RSAKey) if err != nil { return nil, fmt.Errorf("could not convert rsa.PrivateKey to data.PrivateKey: %v", err) } return tufRSAPrivateKey, nil case "EC PRIVATE KEY": var privKeyBytes []byte var err error if x509.IsEncryptedPEMBlock(block) { privKeyBytes, err = x509.DecryptPEMBlock(block, []byte(passphrase)) if err != nil { return nil, errors.New("could not decrypt private key") } } else { privKeyBytes = block.Bytes } ecdsaPrivKey, err := x509.ParseECPrivateKey(privKeyBytes) if err != nil { return nil, fmt.Errorf("could not parse DER encoded private key: %v", err) } tufECDSAPrivateKey, err := ECDSAToPrivateKey(ecdsaPrivKey, data.ECDSAKey) if err != nil { return nil, fmt.Errorf("could not convert ecdsa.PrivateKey to data.PrivateKey: %v", err) } return tufECDSAPrivateKey, nil default: return nil, fmt.Errorf("unsupported key type %q", block.Type) } }
func FuzzPEM(data []byte) int { var b pem.Block err := gob.NewDecoder(bytes.NewReader(data)).Decode(&b) if err != nil { return 0 } b1, err := x509.DecryptPEMBlock(&b, []byte("pass")) if err != nil { return 0 } b2, err := x509.EncryptPEMBlock(zeroReader(0), "msg", b1, []byte("pass1"), x509.PEMCipherDES) if err != nil { panic(err) } _, err = x509.DecryptPEMBlock(b2, []byte("pass")) if err == nil { panic("decoded with a wrong pass") } b3, err := x509.DecryptPEMBlock(b2, []byte("pass1")) if err != nil { panic(err) } if !bytes.Equal(b1, b3) { panic("data changed") } return 1 }
func checkKey(jobs <-chan string, wg *sync.WaitGroup, block *pem.Block) { // https://github.com/golang/go/issues/10171 // golang's fix? expand the documentation ... defer wg.Done() for passwordStr := range jobs { password := []byte(passwordStr) key, err := x509.DecryptPEMBlock(block, password) if err == nil { // we now have a candidate, is it random noise or is can be parsed? // for some reason ParseRawPrivateKey fails so its brute force time // https://github.com/golang/go/issues/8581 - ed25519 are not currently supported by Golang _, err := ssh.ParseDSAPrivateKey(key) if err == nil { printNDie(password) } // not DSA? maybe RSA _, err = x509.ParsePKCS1PrivateKey(key) if err == nil { printNDie(password) } // ECDSA? _, err = x509.ParseECPrivateKey(key) if err == nil { printNDie(password) } } } }
// SSHConfigPubKeyFile is a convience function that takes a username, private key // and passphrase and returns a new ssh.ClientConfig setup to pass credentials // to DialSSH func SSHConfigPubKeyFile(user string, file string, passphrase string) (*ssh.ClientConfig, error) { buf, err := ioutil.ReadFile(file) if err != nil { return nil, err } block, rest := pem.Decode(buf) if len(rest) > 0 { return nil, fmt.Errorf("pem: unable to decode file %s", file) } if x509.IsEncryptedPEMBlock(block) { b := block.Bytes b, err = x509.DecryptPEMBlock(block, []byte(passphrase)) if err != nil { return nil, err } buf = pem.EncodeToMemory(&pem.Block{ Type: block.Type, Bytes: b, }) } key, err := ssh.ParsePrivateKey(buf) if err != nil { return nil, err } return &ssh.ClientConfig{ User: user, Auth: []ssh.AuthMethod{ ssh.PublicKeys(key), }, }, nil }
func LoadCertKeyFromEncPkg(encpkg []byte, passwd string) (*CertKey, error) { blk, _ := pem.Decode(encpkg) if blk == nil { return nil, errors.New("Invalid PEM data") } if blk.Type != pkgTypeStr { return nil, errors.New("PEM type is not " + pkgTypeStr) } decrypted_pem, err := x509.DecryptPEMBlock(blk, []byte(passwd)) if err != nil { return nil, err } key_pem, rest := pem.Decode(decrypted_pem) if blk == nil { return nil, errors.New("decrypted content is not PEM") } cert_pem, _ := pem.Decode(rest) if blk == nil { return nil, errors.New("Can't find the cert PEM") } if _, ok := supportedKeyTypes[key_pem.Type]; !ok { return nil, errors.New("Unsupported Key types") } if cert_pem.Type != "CERTIFICATE" { return nil, errors.New("Can't find certificate in decrypted PEM data") } var ck CertKey switch key_pem.Type { case "RSA PRIVATE KEY": rsack := new(RSACertKey) priv_key, err := x509.ParsePKCS1PrivateKey(key_pem.Bytes) if err != nil { return nil, err } rsack.key = priv_key cert, err := x509.ParseCertificates(cert_pem.Bytes) if err != nil { return nil, err } rsack.cert = *cert[0] ck = rsack return &ck, nil case "EC PRIVATE KEY": ecck := new(ECCertKey) priv_key, err := x509.ParseECPrivateKey(key_pem.Bytes) if err != nil { return nil, err } ecck.key = priv_key cert, err := x509.ParseCertificates(cert_pem.Bytes) if err != nil { return nil, err } ecck.cert = *cert[0] ck = ecck return &ck, nil } return nil, errors.New("Unussal error, you shouldn't see this") }
func readKeyOrGenerate(path, pass string) (*rsa.PrivateKey, error) { file, err := ioutil.ReadFile(path) var key *rsa.PrivateKey if err != nil { log.Printf("Generating new key %s...", path) key, err = rsa.GenerateKey(rand.Reader, rsaBitLength) if err != nil { return nil, err } raw := x509.MarshalPKCS1PrivateKey(key) block, err := x509.EncryptPEMBlock(rand.Reader, blockType, raw, []byte(pass), cipherType) if err != nil { return nil, err } encoded := pem.EncodeToMemory(block) ioutil.WriteFile(path, encoded, 0400) } else { log.Printf("Loading key %s...", path) block, _ := pem.Decode(file) if block == nil { return nil, fmt.Errorf("%s doesn't contain a PEM key", path) } raw, err := x509.DecryptPEMBlock(block, []byte(pass)) if err != nil { return nil, err } key, err = x509.ParsePKCS1PrivateKey(raw) if err != nil { return nil, err } } return key, nil }
func decryptPEM(pemblock *pem.Block, filename string) ([]byte, error) { var err error if _, err = fmt.Fprintf(os.Stderr, "Enter passphrase for %s: ", filename); err != nil { return []byte(""), err } // we already emit the prompt to stderr; GetPass only emits to stdout var passwd string passwd, err = gopass.GetPass("") fmt.Fprintln(os.Stderr, "") if err != nil { return []byte(""), err } var decryptedBytes []byte if decryptedBytes, err = x509.DecryptPEMBlock(pemblock, []byte(passwd)); err != nil { return []byte(""), err } pemBytes := pem.Block{ Type: "RSA PRIVATE KEY", Bytes: decryptedBytes, } decryptedPEM := pem.EncodeToMemory(&pemBytes) return decryptedPEM, nil }
// readKey returns the decrypted key pem bytes, and enforces the KEK if applicable // (writes it back with the correct encryption if it is not correctly encrypted) func (k *KeyReadWriter) readKey() (*pem.Block, error) { keyBlock, err := k.readKeyblock() if err != nil { return nil, err } if !x509.IsEncryptedPEMBlock(keyBlock) { return keyBlock, nil } // If it's encrypted, we can't read without a passphrase (we're assuming // empty passphrases iare invalid) if k.kekData.KEK == nil { return nil, ErrInvalidKEK{Wrapped: x509.IncorrectPasswordError} } derBytes, err := x509.DecryptPEMBlock(keyBlock, k.kekData.KEK) if err != nil { return nil, ErrInvalidKEK{Wrapped: err} } // remove encryption PEM headers headers := make(map[string]string) mergePEMHeaders(headers, keyBlock.Headers) return &pem.Block{ Type: keyBlock.Type, // the key type doesn't change Bytes: derBytes, Headers: headers, }, nil }
func _passwordDecoding(encodedpassword, passpharse []byte, priblock *pem.Block) (password []byte, err error) { //decode with base64 _encodedpassword, err := base64.StdEncoding.DecodeString(string(encodedpassword)) if err != nil { return } //compare to private key priByte, err := x509.DecryptPEMBlock(priblock, passpharse) if err != nil { return } pri, err := x509.ParsePKCS1PrivateKey(priByte) if err != nil { return } //decode with rsa password, err = rsa.DecryptPKCS1v15(rand.Reader, pri, _encodedpassword) if err != nil { return } return }
func (crtkit CertKit) ReadDecryptRsaPrivKeyFromReader(r io.Reader) (*rsa.PrivateKey, []byte, error) { var err error var pembuf []byte var key *rsa.PrivateKey var plainkey []byte var block *pem.Block pembuf, err = ioutil.ReadAll(r) if err != nil { Goose.Loader.Logf(1, "Failed reading Key %s", err) return nil, nil, err } block, _ = pem.Decode(pembuf) plainkey, err = x509.DecryptPEMBlock(block, []byte{}) Goose.Loader.Logf(1, "DecryptPEMBlock: %s", plainkey) if err != nil { return nil, nil, err } key, err = x509.ParsePKCS1PrivateKey(plainkey) if err != nil { Goose.Loader.Logf(1, "Failed parsing key %s", err) return nil, nil, err } return key, pem.EncodeToMemory(&pem.Block{ Type: "RSA PRIVATE KEY", // Headers map[string]string // Optional headers. Bytes: plainkey, }), nil }
// PEMtoPublicKey unmarshals a pem to public key func PEMtoPublicKey(raw []byte, pwd []byte) (interface{}, error) { block, _ := pem.Decode(raw) // TODO: derive from header the type of the key if x509.IsEncryptedPEMBlock(block) { if pwd == nil { return nil, errors.New("Encrypted Key. Need a password!!!") } decrypted, err := x509.DecryptPEMBlock(block, pwd) if err != nil { return nil, errors.New("Failed decryption!!!") } key, err := DERToPublicKey(decrypted) if err != nil { return nil, err } return key, err } cert, err := DERToPublicKey(block.Bytes) if err != nil { return nil, err } return cert, err }
// processPrivateKeyFile takes a private key file and an optional passphrase // and decodes it to a byte slice. func processPrivateKeyFile(privateKeyFile, passphrase string) ([]byte, error) { rawPrivateKeyBytes, err := ioutil.ReadFile(privateKeyFile) if err != nil { return nil, fmt.Errorf("Failed loading private key file: %s", err) } PEMBlock, _ := pem.Decode(rawPrivateKeyBytes) if PEMBlock == nil { return nil, fmt.Errorf( "%s does not contain a vaild private key", privateKeyFile) } if x509.IsEncryptedPEMBlock(PEMBlock) { if passphrase == "" { return nil, errors.New("a passphrase must be specified when using an encrypted private key") } decryptedPrivateKeyBytes, err := x509.DecryptPEMBlock(PEMBlock, []byte(passphrase)) if err != nil { return nil, fmt.Errorf("Failed decrypting private key: %s", err) } b := &pem.Block{ Type: "RSA PRIVATE KEY", Bytes: decryptedPrivateKeyBytes, } return pem.EncodeToMemory(b), nil } return rawPrivateKeyBytes, nil }
/* Given a PEM block in a string e.g. ----- BEGIN RSA PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQClbkoOcBAXWJpRh9x+qEHRVvLs DjatUqRN/rHmH3rZkdjFEFb/7bFitMDyg6EqiKOU3/Umq3KRy7MHzqv84LHf1c2V CAltWyuLbfXWce9jd8CSHLI8Jwpw4lmOb/idGfEFrMLT8Ms18pKA4Thrb2TE7yLh 4fINDOjP+yJJvZohNwIDAQAB ----- END RSA PUBLIC KEY----- Returns the decoding of the base-64 into a byte slice. Also returns the block type, in this case "RSA PUBLIC KEY" */ func DecodePEM(pemBlock string, password string) (decoded []byte, blockType string, err error) { var blk *pem.Block pb := ([]byte)(pemBlock) blk, _ = pem.Decode(pb) if blk == nil { err = errors.New("DecodePEM: No PEM block found.") return } /* Awaiting Go 1.1 */ if password != "" { passwordBytes := ([]byte)(password) decoded, err = x509.DecryptPEMBlock(blk, passwordBytes) } else { /* */ decoded = blk.Bytes /* Awaiting Go 1.1 */ } /* */ blockType = blk.Type return }
// ReadPrivateKey attempts to read your private key and possibly decrypt it if it // requires a passphrase. // This function will prompt for a passphrase on STDIN if the environment variable (`IDENTITY_PASSPHRASE`), // is not set. func ReadPrivateKey(path string) ([]byte, error) { privateKey, err := ioutil.ReadFile(path) if err != nil { return nil, fmt.Errorf("failed to load identity: %v", err) } block, rest := pem.Decode(privateKey) if len(rest) > 0 { return nil, fmt.Errorf("extra data when decoding private key") } if !x509.IsEncryptedPEMBlock(block) { return privateKey, nil } passphrase := os.Getenv("IDENTITY_PASSPHRASE") if passphrase == "" { passphrase, err = gopass.GetPass("Enter passphrase: ") if err != nil { return nil, fmt.Errorf("couldn't read passphrase: %v", err) } } der, err := x509.DecryptPEMBlock(block, []byte(passphrase)) if err != nil { return nil, fmt.Errorf("decrypt failed: %v", err) } privateKey = pem.EncodeToMemory(&pem.Block{ Type: block.Type, Bytes: der, }) return privateKey, nil }
func _passwordListDecoding(encodedpassword [][]byte, passpharse []byte, priblock *pem.Block) (password [][]byte, err error) { //decode with base64 encodedpasswordList := make([][]byte, len(encodedpassword)) for i, e := range encodedpassword { encodedpasswordList[i], err = base64.StdEncoding.DecodeString(string(e)) if err != nil { return } } //compare to private key priByte, err := x509.DecryptPEMBlock(priblock, passpharse) if err != nil { return } pri, err := x509.ParsePKCS1PrivateKey(priByte) if err != nil { return } //decode with rsa password = make([][]byte, len(encodedpasswordList)) for i, e := range encodedpasswordList { password[i], err = rsa.DecryptPKCS1v15(rand.Reader, pri, e) } if err != nil { return } return }
func LoadCertsKeys(uname string, upass []byte) (ca []byte, ee []byte, pkey []byte, err error) { user_dir := common.GetConfDir(uname) cafs, err := ioutil.ReadFile(filepath.Join(user_dir, "ca.cert")) if err != nil { return nil, nil, nil, err } ca, err = passcrypto.DecryptMeBase32(string(cafs), upass) if err != nil { return nil, nil, nil, err } ee_pem, err := ioutil.ReadFile(filepath.Join(user_dir, "ee.cert")) if err != nil { return nil, nil, nil, err } ee_blk, _ := pem.Decode(ee_pem) ee = ee_blk.Bytes pkeyfs, err := ioutil.ReadFile(filepath.Join(user_dir, "ee.key")) if err != nil { return nil, nil, nil, err } pkey_pem, _ := pem.Decode(pkeyfs) pkey, err = x509.DecryptPEMBlock(pkey_pem, upass) if err != nil { return nil, nil, nil, err } return }
// PEMtoPublicKey unmarshals a pem to public key func PEMtoPublicKey(raw []byte, pwd []byte) (interface{}, error) { if len(raw) == 0 { return nil, utils.ErrNilArgument } block, _ := pem.Decode(raw) if block == nil { return nil, fmt.Errorf("Failed decoding [% x]", raw) } // TODO: derive from header the type of the key if x509.IsEncryptedPEMBlock(block) { if len(pwd) == 0 { return nil, errors.New("Encrypted Key. Need a password!!!") } decrypted, err := x509.DecryptPEMBlock(block, pwd) if err != nil { return nil, errors.New("Failed decryption!!!") } key, err := DERToPublicKey(decrypted) if err != nil { return nil, err } return key, err } cert, err := DERToPublicKey(block.Bytes) if err != nil { return nil, err } return cert, err }
func loadECertAndEnrollmentPrivateKey(enrollmentID string, password string) ([]byte, *ecdsa.PrivateKey, error) { cooked, err := ioutil.ReadFile("./test_resources/key_" + enrollmentID + ".dump") if err != nil { return nil, nil, err } block, _ := pem.Decode(cooked) decryptedBlock, err := x509.DecryptPEMBlock(block, []byte(password)) if err != nil { return nil, nil, err } enrollmentPrivateKey, err := x509.ParseECPrivateKey(decryptedBlock) if err != nil { return nil, nil, err } if err != nil { return nil, nil, err } ecertRaw, err := ioutil.ReadFile("./test_resources/ecert_" + enrollmentID + ".dump") if err != nil { return nil, nil, err } return ecertRaw, enrollmentPrivateKey, nil }
func TestDecrypt(t *testing.T) { block, rest := pem.Decode(testData[0].privateKey) if len(rest) > 0 { t.Error("extra data") } der, err := x509.DecryptPEMBlock(block, []byte(testData[0].passphrase)) if err != nil { t.Error("decrypt failed: ", err) } var privateKey *rsa.PrivateKey if privateKey, err = x509.ParsePKCS1PrivateKey(der); err != nil { t.Error("private key failed: ", err) } b, _ := base64.StdEncoding.DecodeString(testData[0].encryptedMessage) decrypted, err := rsa.DecryptPKCS1v15(rand.Reader, privateKey, b) if err != nil { t.Error("failed to decrypt, ", err) } assert.Equal(t, testData[0].decryptedMessage, string(decrypted), "should be the same") }
func server(config Config) { // open receive port readSocket := openUDPSocket(`r`, net.UDPAddr{ IP: net.IPv4(0, 0, 0, 0), Port: config.Port, }) fmt.Printf("Listening on UDP port %d...\n", config.Port) defer readSocket.Close() // main loop for { data := make([]byte, UDP_MSG_SIZE) size, clientAddr, err := readSocket.ReadFromUDP(data) if err != nil { fmt.Println("Error reading from receive port: ", err) } clientMsg := data[0:size] if string(clientMsg) == KEY_REQUEST_TEXT { fmt.Printf("Received key request from %s, sending key.\n", clientAddr.IP) // reply to the client on the same port writeSocket := openUDPSocket(`w`, net.UDPAddr{ IP: clientAddr.IP, Port: clientAddr.Port + 1, }) var keyData []byte keyData = []byte(os.Getenv(KEY_DATA_ENV_VAR)) if len(keyData) == 0 { keyData, err = ioutil.ReadFile(config.KeyPath) if err != nil { fmt.Printf("ERROR reading keyfile %s: %s!\n", config.KeyPath, err) } } pemBlock, _ := pem.Decode(keyData) if pemBlock != nil { if x509.IsEncryptedPEMBlock(pemBlock) { fmt.Println("Decrypting private key with passphrase...") decoded, err := x509.DecryptPEMBlock(pemBlock, []byte(config.Pwd)) if err == nil { header := `PRIVATE KEY` // default key type in header matcher := regexp.MustCompile("-----BEGIN (.*)-----") if matches := matcher.FindSubmatch(keyData); len(matches) > 1 { header = string(matches[1]) } keyData = pem.EncodeToMemory( &pem.Block{Type: header, Bytes: decoded}) } else { fmt.Printf("Error decrypting PEM-encoded secret: %s\n", err) } } } _, err = writeSocket.Write(keyData) if err != nil { fmt.Printf("ERROR writing data to socket:%s!\n", err) } writeSocket.Close() } } }
// PEMtoPublicKey unmarshals a pem to public key func PEMtoPublicKey(raw []byte, pwd []byte) (interface{}, error) { if len(raw) == 0 { return nil, errors.New("Invalid PEM. It must be diffrent from nil.") } block, _ := pem.Decode(raw) if block == nil { return nil, fmt.Errorf("Failed decoding. Block must be different from nil. [% x]", raw) } // TODO: derive from header the type of the key if x509.IsEncryptedPEMBlock(block) { if len(pwd) == 0 { return nil, errors.New("Encrypted Key. Password must be different from nil") } decrypted, err := x509.DecryptPEMBlock(block, pwd) if err != nil { return nil, fmt.Errorf("Failed PEM decryption. [%s]", err) } key, err := DERToPublicKey(decrypted) if err != nil { return nil, err } return key, err } cert, err := DERToPublicKey(block.Bytes) if err != nil { return nil, err } return cert, err }
/* With help from: * https://stackoverflow.com/questions/14404757/how-to-encrypt-and-decrypt-plain-text-with-a-rsa-keys-in-go */ func getRSAKeyFromSSHFile(keyFile string) (key *rsa.PrivateKey) { verbose(fmt.Sprintf("Extracting RSA key from '%s'...", keyFile), 3) pemData, err := ioutil.ReadFile(keyFile) if err != nil { fail(fmt.Sprintf("Unable to read '%s'.\n", keyFile)) } block, _ := pem.Decode(pemData) if block == nil { fail(fmt.Sprintf("Unable to PEM-decode '%s'.\n", keyFile)) } if got, want := block.Type, "RSA PRIVATE KEY"; got != want { fail(fmt.Sprintf("Unknown key type %q.\n", got)) } keyBytes := block.Bytes if strings.Contains(string(pemData), "Proc-Type: 4,ENCRYPTED") { password := getpass(fmt.Sprintf("Enter pass phrase for %s: ", keyFile)) keyBytes, err = x509.DecryptPEMBlock(block, password) if err != nil { fail(fmt.Sprintf("Unable to decrypt private key: %v\n", err)) } } key, err = x509.ParsePKCS1PrivateKey(keyBytes) if err != nil { fail(fmt.Sprintf("Unable to extract private key from PEM data: %v\n", err)) } return }
// Read a PEM file and ask for a password to decrypt it if needed func ReadPEMData(pemFile string, pemPass []byte) ([]byte, error) { pemData, err := ioutil.ReadFile(pemFile) if err != nil { return pemData, err } // We should really just get the pem.Block back here, if there's other // junk on the end, warn about it. pemBlock, rest := pem.Decode(pemData) if len(rest) > 0 { log.Warning("Didn't parse all of", pemFile) } if x509.IsEncryptedPEMBlock(pemBlock) { // Decrypt and get the ASN.1 DER bytes here pemData, err = x509.DecryptPEMBlock(pemBlock, pemPass) if err != nil { return pemData, err } else { log.Info("Decrypted", pemFile, "successfully") } // Shove the decrypted DER bytes into a new pem Block with blank headers var newBlock pem.Block newBlock.Type = pemBlock.Type newBlock.Bytes = pemData // This is now like reading in an uncrypted key from a file and stuffing it // into a byte stream pemData = pem.EncodeToMemory(&newBlock) } return pemData, nil }
func readPEMFile(path, passphrase string) ([]byte, error) { pass := []byte(passphrase) var blocks []*pem.Block content, err := ioutil.ReadFile(path) if err != nil { return nil, err } for len(content) > 0 { var block *pem.Block block, content = pem.Decode(content) if block == nil { if len(blocks) == 0 { return nil, errors.New("no pem file") } break } if x509.IsEncryptedPEMBlock(block) { var buffer []byte var err error if len(pass) == 0 { err = errors.New("No passphrase available") } else { // Note, decrypting pem might succeed even with wrong password, but // only noise will be stored in buffer in this case. buffer, err = x509.DecryptPEMBlock(block, pass) } if err != nil { logp.Err("Dropping encrypted pem '%v' block read from %v. %v", block.Type, path, err) continue } // DEK-Info contains encryption info. Remove header to mark block as // unencrypted. delete(block.Headers, "DEK-Info") block.Bytes = buffer } blocks = append(blocks, block) } if len(blocks) == 0 { return nil, errors.New("no PEM blocks") } // re-encode available, decrypted blocks buffer := bytes.NewBuffer(nil) for _, block := range blocks { err := pem.Encode(buffer, block) if err != nil { return nil, err } } return buffer.Bytes(), nil }
// import private key from pem format func importPrivateKeyfromEncryptedPEM(pemsec, password []byte) *ecdsa.PrivateKey { block, _ := pem.Decode(pemsec) //log.Print(block) buf, _ := x509.DecryptPEMBlock(block, password) sec, _ := x509.ParseECPrivateKey(buf) //log.Print(sec) return sec }
func LoadManpassCA(uname string, passwd []byte) (*CertKey, error) { //generate a new EE cert/key with specified uname's CA //return encrypted CA cert, EE cert and encrypted EE key in a string confdir := common.GetConfDir(uname) fi, err := os.Stat(confdir) if err != nil { return nil, err } if !fi.IsDir() { return nil, fmt.Errorf("%s is not a directory", confdir) } encacs, err := ioutil.ReadFile(filepath.Join(confdir, "ca.cert")) if err != nil { return nil, err } cacert_der, err := passcrypto.DecryptMeBase32(string(encacs), passwd) if err != nil { return nil, err } encaks, err := ioutil.ReadFile(filepath.Join(confdir, "ca.key")) if err != nil { return nil, err } blk, _ := pem.Decode(encaks) cakey_der, err := x509.DecryptPEMBlock(blk, passwd) var ck CertKey switch blk.Type { case "RSA PRIVATE KEY": ca := new(RSACertKey) cakey, err := x509.ParsePKCS1PrivateKey(cakey_der) if err != nil { return nil, err } ca.key = cakey cert, err := x509.ParseCertificates(cacert_der) if err != nil { return nil, err } ca.cert = *cert[0] ck = ca return &ck, nil case "EC PRIVATE KEY": ecck := new(ECCertKey) priv_key, err := x509.ParseECPrivateKey(cakey_der) if err != nil { return nil, err } ecck.key = priv_key cert, err := x509.ParseCertificates(cacert_der) if err != nil { return nil, err } ecck.cert = *cert[0] ck = ecck return &ck, nil } return nil, errors.New("Unussal error, you shouldn't see this") }
// ParsePEMPrivateKey returns a data.PrivateKey from a PEM encoded private key. It // only supports RSA (PKCS#1) and attempts to decrypt using the passphrase, if encrypted. func ParsePEMPrivateKey(pemBytes []byte, passphrase string) (data.PrivateKey, error) { block, _ := pem.Decode(pemBytes) if block == nil { return nil, errors.New("no valid private key found") } var privKeyBytes []byte var err error if x509.IsEncryptedPEMBlock(block) { privKeyBytes, err = x509.DecryptPEMBlock(block, []byte(passphrase)) if err != nil { return nil, errors.New("could not decrypt private key") } } else { privKeyBytes = block.Bytes } switch block.Type { case "RSA PRIVATE KEY": rsaPrivKey, err := x509.ParsePKCS1PrivateKey(privKeyBytes) if err != nil { return nil, fmt.Errorf("could not parse DER encoded key: %v", err) } tufRSAPrivateKey, err := RSAToPrivateKey(rsaPrivKey) if err != nil { return nil, fmt.Errorf("could not convert rsa.PrivateKey to data.PrivateKey: %v", err) } return tufRSAPrivateKey, nil case "EC PRIVATE KEY": ecdsaPrivKey, err := x509.ParseECPrivateKey(privKeyBytes) if err != nil { return nil, fmt.Errorf("could not parse DER encoded private key: %v", err) } tufECDSAPrivateKey, err := ECDSAToPrivateKey(ecdsaPrivKey) if err != nil { return nil, fmt.Errorf("could not convert ecdsa.PrivateKey to data.PrivateKey: %v", err) } return tufECDSAPrivateKey, nil case "ED25519 PRIVATE KEY": // We serialize ED25519 keys by concatenating the private key // to the public key and encoding with PEM. See the // ED25519ToPrivateKey function. tufECDSAPrivateKey, err := ED25519ToPrivateKey(privKeyBytes) if err != nil { return nil, fmt.Errorf("could not convert ecdsa.PrivateKey to data.PrivateKey: %v", err) } return tufECDSAPrivateKey, nil default: return nil, fmt.Errorf("unsupported key type %q", block.Type) } }
// Pem2PrivateKey converts a PEM encoded private key with an optional password to a *rsa.PrivateKey func Pem2PrivateKey(privatekeypem, pw string) (privatekey *rsa.PrivateKey) { block, _ := pem.Decode([]byte(privatekeypem)) if pw != "" { privbytes, _ := x509.DecryptPEMBlock(block, []byte(pw)) privatekey, _ = x509.ParsePKCS1PrivateKey(privbytes) } else { privatekey, _ = x509.ParsePKCS1PrivateKey(block.Bytes) } return }
func unencryptPrivateKey(block *pem.Block, password string) (crypto.PrivateKey, error) { if x509.IsEncryptedPEMBlock(block) { bytes, err := x509.DecryptPEMBlock(block, []byte(password)) if err != nil { return nil, ErrFailedToDecryptKey } return parsePrivateKey(bytes) } return parsePrivateKey(block.Bytes) }
// AddPEMKeyPassword adds a PEM encoded private key that is protected by // a password to the keychain. func (k *SimpleKeychain) AddPEMKeyPassword(key string, password string) (err error) { block, _ := pem.Decode([]byte(key)) bytes, _ := x509.DecryptPEMBlock(block, []byte(password)) rsakey, err := x509.ParsePKCS1PrivateKey(bytes) if err != nil { return } k.keys = append(k.keys, rsakey) return }