Beispiel #1
0
// 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)
	}
}
Beispiel #2
0
// 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
}
Beispiel #3
0
// 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
}
Beispiel #4
0
// 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
}
Beispiel #5
0
func addKeyAuth(auths []ssh.AuthMethod, keypath string) []ssh.AuthMethod {
	if len(keypath) == 0 {
		return auths
	}

	keypath = expandPath(keypath)

	// read the file
	pemBytes, err := ioutil.ReadFile(keypath)
	if err != nil {
		log.Print(err)
		os.Exit(1)
	}

	// get first pem block
	block, _ := pem.Decode(pemBytes)
	if block == nil {
		log.Printf("no key found in %s", keypath)
		return auths
	}

	// handle plain and encrypted keyfiles
	if x509.IsEncryptedPEMBlock(block) {
		log.Printf("warning: ignoring encrypted key '%s'", keypath)
		return auths
	} else {
		signer, err := ssh.ParsePrivateKey(pemBytes)
		if err != nil {
			log.Print(err)
			return auths
		}
		return append(auths, ssh.PublicKeys(signer))
	}
}
Beispiel #6
0
// 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
}
Beispiel #7
0
// 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
}
Beispiel #8
0
// 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
}
Beispiel #9
0
// 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

}
Beispiel #10
0
// 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
}
Beispiel #11
0
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()
		}
	}
}
Beispiel #12
0
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
}
Beispiel #13
0
// 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)
	}
}
Beispiel #14
0
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)
}
Beispiel #15
0
// Determine if PEM file is encrypted
func IsEncryptedPEM(pemFile string) bool {
	pemData, err := ioutil.ReadFile(pemFile)
	if err != nil {
		return false
	}
	pemBlock, _ := pem.Decode(pemData)
	if len(pemBlock.Bytes) == 0 {
		return false
	}
	return x509.IsEncryptedPEMBlock(pemBlock)
}
Beispiel #16
0
func loadPrivateKey(path string) (ssh.AuthMethod, error) {
	// Read file
	keyData, err := ioutil.ReadFile(path)
	if err != nil {
		log.Printf("error: could not read key file '%s': %s", path, err)
		return nil, err
	}

	// Get first PEM block
	block, _ := pem.Decode(keyData)
	if err != nil {
		log.Printf("error: no key found in file '%s': %s", path, err)
		return nil, err
	}

	// If it's encrypted...
	var (
		signer    ssh.Signer
		signerErr error
	)

	if x509.IsEncryptedPEMBlock(block) {
		// Get the passphrase
		prompt := fmt.Sprintf("Enter passphrase for key '%s': ", path)
		pass, err := speakeasy.Ask(prompt)
		if err != nil {
			log.Printf("error: error getting passphrase: %s", err)
			return nil, err
		}

		block.Bytes, err = x509.DecryptPEMBlock(block, []byte(pass))
		if err != nil {
			log.Printf("error: error decrypting key: %s", err)
			return nil, err
		}

		key, err := ParsePEMBlock(block)
		if err != nil {
			log.Printf("error: could not parse PEM block: %s", err)
			return nil, err
		}

		signer, signerErr = ssh.NewSignerFromKey(key)
	} else {
		signer, signerErr = ssh.ParsePrivateKey(keyData)
	}

	if signerErr != nil {
		log.Printf("error: error parsing private key '%s': %s", path, signerErr)
		return nil, signerErr
	}

	return ssh.PublicKeys(signer), nil
}
Beispiel #17
0
// checkRootKeyIsEncrypted makes sure the root key is encrypted. We have
// internal assumptions that depend on this.
func checkRootKeyIsEncrypted(pemBytes []byte) error {
	block, _ := pem.Decode(pemBytes)
	if block == nil {
		return ErrNoValidPrivateKey
	}

	if !x509.IsEncryptedPEMBlock(block) {
		return ErrRootKeyNotEncrypted
	}

	return nil
}
Beispiel #18
0
func (a *SAuth) signInWithKey() (*signinResponse, error) {
	body := struct {
		PublicKey string `json:"publicKey"`
		Signature string `json:"signature"`
	}{}

	bytes, err := ioutil.ReadFile(a.Settings.PrivateKeyPath)
	if err != nil {
		return nil, err
	}
	block, _ := pem.Decode(bytes)
	if block == nil {
		return nil, errors.New("Private key is not PEM-encoded")
	}
	bytes = block.Bytes
	if x509.IsEncryptedPEMBlock(block) {
		passphrase := a.Prompts.KeyPassphrase(a.Settings.PrivateKeyPath)
		bytes, err = x509.DecryptPEMBlock(block, []byte(passphrase))
		if err != nil {
			return nil, err
		}
	}
	privateKey, err := x509.ParsePKCS1PrivateKey(bytes)
	if err != nil {
		return nil, err
	}
	publicKey, err := ioutil.ReadFile(a.Settings.PrivateKeyPath + ".pub")
	if err != nil {
		return nil, err
	}
	body.PublicKey = string(publicKey)

	headers := httpclient.GetHeaders(a.Settings.SessionToken, a.Settings.Version, a.Settings.Pod, a.Settings.UsersID)
	message := fmt.Sprintf("%s&%s", headers["X-Request-Nonce"][0], headers["X-Request-Timestamp"][0])
	hashedMessage := sha256.Sum256([]byte(message))
	signature, err := privateKey.Sign(rand.Reader, hashedMessage[:], crypto.SHA256)
	if err != nil {
		return nil, err
	}
	body.Signature = base64.StdEncoding.EncodeToString(signature)

	b, err := json.Marshal(body)
	if err != nil {
		return nil, err
	}
	resp, statusCode, err := httpclient.Post(b, fmt.Sprintf("%s%s/auth/signin/key", a.Settings.AuthHost, a.Settings.AuthHostVersion), headers)
	if err != nil {
		return nil, err
	}
	signinResp := &signinResponse{}
	return signinResp, httpclient.ConvertResp(resp, statusCode, signinResp)
}
Beispiel #19
0
func parseKey(block *pem.Block, passphrase []byte) (*rsa.PrivateKey, error) {
	var blockBytes []byte
	if x509.IsEncryptedPEMBlock(block) {
		b, err := x509.DecryptPEMBlock(block, passphrase)
		if err != nil {
			return nil, err
		}
		blockBytes = b
	} else {
		blockBytes = block.Bytes
	}
	return x509.ParsePKCS1PrivateKey(blockBytes)
}
Beispiel #20
0
func addKeyAuth(auths []ssh.AuthMethod, keypath string) []ssh.AuthMethod {
	if len(keypath) == 0 {
		return auths
	}

	// read the file
	pemBytes, err := ioutil.ReadFile(keypath)
	if err != nil {
		log.Print(err)
		os.Exit(1)
	}

	// get first pem block
	block, _ := pem.Decode(pemBytes)
	if block == nil {
		log.Printf("no key found in %s", keypath)
		return auths
	}

	// handle plain and encrypted keyfiles
	if x509.IsEncryptedPEMBlock(block) {
		prompt := fmt.Sprintf("Enter passphrase for key '%s': ", keypath)
		pass, err := getpass(prompt)
		if err != nil {
			return auths
		}
		block.Bytes, err = x509.DecryptPEMBlock(block, []byte(pass))
		if err != nil {
			log.Print(err)
			return auths
		}
		key, err := ParsePemBlock(block)
		if err != nil {
			log.Print(err)
			return auths
		}
		signer, err := ssh.NewSignerFromKey(key)
		if err != nil {
			log.Print(err)
			return auths
		}
		return append(auths, ssh.PublicKeys(signer))
	} else {
		signer, err := ssh.ParsePrivateKey(pemBytes)
		if err != nil {
			log.Print(err)
			return auths
		}
		return append(auths, ssh.PublicKeys(signer))
	}
}
Beispiel #21
0
func (c *SSHCluster) findSSHKeySigners() (signers []privateKeySigner) {
	keyDir := filepath.Join(c.sshDir())
	if stat, err := os.Stat(keyDir); err != nil || !stat.IsDir() {
		return
	}
	walkFunc := func(path string, info os.FileInfo, err error) error {
		if info.IsDir() {
			return nil
		}
		if strings.HasSuffix(path, ".pub") {
			return nil
		}
		data, err := ioutil.ReadFile(path)
		if err != nil {
			return nil
		}
		b, _ := pem.Decode(data)
		if b == nil {
			return nil
		}
		s := privateKeySigner{
			base:      c.base,
			path:      path,
			pem:       b,
			Encrypted: x509.IsEncryptedPEMBlock(b),
		}
		if s.Encrypted {
			publicKeyPath := fmt.Sprintf("%s.pub", path)
			if stat, err := os.Stat(publicKeyPath); err == nil && !stat.IsDir() {
				if data, err := ioutil.ReadFile(publicKeyPath); err == nil {
					pk, _, _, _, err := ssh.ParseAuthorizedKey(data)
					if err == nil {
						s.publicKey = pk
					}
				}
			}
			signers = append(signers, s)
			return nil
		}
		privateKey, err := x509.ParsePKCS1PrivateKey(b.Bytes)
		if err != nil {
			return nil
		}
		s.key = privateKey
		signers = append(signers, s)
		return nil
	}
	filepath.Walk(keyDir, walkFunc)
	sort.Sort(decryptedFirst(signers))
	return
}
Beispiel #22
0
func DecryptPemBlock(block *pem.Block, prompt func() (string, error)) (err error) {
	if x509.IsEncryptedPEMBlock(block) {
		if password, err := prompt(); nil != err {
			return err
		} else if data, err := x509.DecryptPEMBlock(block, []byte(password)); nil != err {
			return err
		} else {
			delete(block.Headers, "Proc-Type")
			delete(block.Headers, "DEK-Info")
			block.Bytes = data
		}
	}
	return nil
}
Beispiel #23
0
func (c *Connection) newCertificate() (*tls.Certificate, error) {
	var certPEMBlock *pem.Block
	var keyPEMBlock *pem.Block
	var rest []byte

	rest = c.certificate
	for {
		certPEMBlock, rest = pem.Decode(rest)
		if certPEMBlock == nil || certPEMBlock.Type == "CERTIFICATE" {
			break
		}
	}

	if certPEMBlock == nil {
		return nil, errors.New("Failed to parse certificate data")
	}

	rest = c.certificate
	for {
		keyPEMBlock, rest = pem.Decode(rest)
		if keyPEMBlock == nil || keyPEMBlock.Type == "RSA PRIVATE KEY" {
			break
		}
	}

	if keyPEMBlock == nil {
		return nil, errors.New("Failed to parse key data")
	}

	if x509.IsEncryptedPEMBlock(keyPEMBlock) {
		der, err := x509.DecryptPEMBlock(keyPEMBlock, c.passphrase)

		if err != nil {
			return nil, errors.New("Failed to decrypt: wrong passphrase")
		}

		keyPEMBlock = &pem.Block{
			Type:    keyPEMBlock.Type,
			Headers: keyPEMBlock.Headers,
			Bytes:   der,
		}
	}

	certBytes := pem.EncodeToMemory(certPEMBlock)
	keyBytes := pem.EncodeToMemory(keyPEMBlock)

	cert, err := tls.X509KeyPair(certBytes, keyBytes)

	return &cert, err
}
Beispiel #24
0
// SetRSA reads PEM byte data and decodes it and parses the private key.
// Applies the private and the public key to the AuthManager. Password as second
// argument is only required when the private key is encrypted.
// Checks for io.Close and closes the resource. Public key will be derived from
// the private key. Default Signing bits 256.
func SetRSA(privateKey io.Reader, password ...[]byte) OptionFunc {
	if cl, ok := privateKey.(io.Closer); ok {
		defer func() {
			if err := cl.Close(); err != nil { // close file
				log.Error("userjwt.RSAKey.ioCloser", "err", err)
			}
		}()
	}
	prKeyData, errRA := ioutil.ReadAll(privateKey)
	if errRA != nil {
		return func(a *AuthManager) {
			a.lastError = errgo.Mask(errRA)
		}
	}
	var prKeyPEM *pem.Block
	if prKeyPEM, _ = pem.Decode(prKeyData); prKeyPEM == nil {
		return func(a *AuthManager) {
			a.lastError = errgo.New("Private Key from io.Reader no found")
		}
	}

	var rsaPrivateKey *rsa.PrivateKey
	var err error
	if x509.IsEncryptedPEMBlock(prKeyPEM) {
		if len(password) != 1 || len(password[0]) == 0 {
			return func(a *AuthManager) {
				a.lastError = errgo.New("Private Key is encrypted but password was not set")
			}
		}
		var dd []byte
		var errPEM error
		if dd, errPEM = x509.DecryptPEMBlock(prKeyPEM, password[0]); errPEM != nil {
			return func(a *AuthManager) {
				a.lastError = errgo.Newf("Private Key decryption failed: %s", errPEM.Error())
			}
		}
		rsaPrivateKey, err = x509.ParsePKCS1PrivateKey(dd)
	} else {
		rsaPrivateKey, err = x509.ParsePKCS1PrivateKey(prKeyPEM.Bytes)
	}

	return func(a *AuthManager) {
		a.SigningMethod = jwt.SigningMethodRS256
		a.rsapk = rsaPrivateKey
		a.hasKey = true
		a.lastError = errgo.Mask(err)
	}
}
Beispiel #25
0
func loadSigningKey() (*rsa.PrivateKey, error) {

	// Verify that we have a key path.
	if *keyPath == "" {
		return nil, fmt.Errorf("missing required parameter: key-path")
	}

	// Read the key file.
	pemData, err := ioutil.ReadFile(*keyPath)
	if err != nil {
		return nil, fmt.Errorf("unable to read private key file: %s", err)
	}

	// Extract the PEM-encoded data block.
	block, _ := pem.Decode(pemData)
	if block == nil {
		return nil, fmt.Errorf("bad private key data: not PEM-encoded")
	}
	if got, want := block.Type, "RSA PRIVATE KEY"; got != want {
		return nil, fmt.Errorf("unknown key type %q: expected %q", got, want)
	}

	// Get the key bytes.
	keyBytes := []byte(nil)
	if x509.IsEncryptedPEMBlock(block) {

		// We need the password if the key is encrypted.
		if *keyPassword == "" {
			return nil, fmt.Errorf("no password provided for private key")
		}

		// Decrypt the data block.
		keyBytes, err = x509.DecryptPEMBlock(block, []byte(*keyPassword))
		if err != nil {
			return nil, fmt.Errorf("unable to decrypt private key: %s", err)
		}
	} else {
		keyBytes = block.Bytes
	}

	// Decode the private key.
	privateKey, err := x509.ParsePKCS1PrivateKey(keyBytes)
	if err != nil {
		return nil, fmt.Errorf("bad private key: %s", err)
	}

	return privateKey, nil
}
Beispiel #26
0
// PEMtoAES extracts from the PEM an AES key
func PEMtoAES(raw []byte, pwd []byte) ([]byte, error) {
	block, _ := pem.Decode(raw)

	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, err
		}
		return decrypted, nil
	}

	return block.Bytes, nil
}
Beispiel #27
0
func loadAndDecryptKey(filename string) (*pem.Block, error) {
	f, err := os.Open(filename)
	if err != nil {
		return nil, err
	}
	defer f.Close()

	data, err := ioutil.ReadAll(f)
	if err != nil {
		return nil, err
	}

	block, _ := pem.Decode(data)
	if block == nil {
		return nil, err
	}

	if x509.IsEncryptedPEMBlock(block) {
		var passphrase string
		var decryptedBytes []byte
		for i := 0; i < 3; i++ {
			passphrase, err = ask.HiddenAsk("Passphrase: ")
			if err != nil {
				return nil, err
			}

			decryptedBytes, err = x509.DecryptPEMBlock(block, []byte(passphrase))
			if err == nil {
				break
			}
			if err != x509.IncorrectPasswordError {
				return nil, err
			}
		}

		if err != nil {
			return nil, err
		}

		return &pem.Block{
			Type:  block.Type,
			Bytes: decryptedBytes,
		}, nil
	}
	return block, nil
}
Beispiel #28
0
func (c *SSHCluster) importSSHKeyPair(t *TargetServer) error {
	var buf bytes.Buffer
	_, file, readFileErrChan := c.base.PromptFileInput(fmt.Sprintf("Please provide your private key for %s@%s", t.User, t.IP))
	if _, err := io.Copy(&buf, file); err != nil {
		readFileErrChan <- err
		return err
	}
	readFileErrChan <- nil // no error reading file
	b, _ := pem.Decode(buf.Bytes())
	if b == nil {
		return fmt.Errorf("Invalid private key")
	}
	var pemBytes []byte
	if x509.IsEncryptedPEMBlock(b) {
		passphrase := c.base.PromptProtectedInput("Please enter the passphrase for the key")
		var err error
		pemBytes, err = x509.DecryptPEMBlock(b, []byte(passphrase))
		if err != nil {
			return err
		}
	} else {
		pemBytes = b.Bytes
	}
	privateKey, err := x509.ParsePKCS1PrivateKey(pemBytes)
	if err != nil {
		return err
	}

	signer, err := ssh.NewSignerFromKey(privateKey)
	if err != nil {
		return err
	}
	auth := []ssh.AuthMethod{ssh.PublicKeys(signer)}

	sshConfig := c.sshConfigForAuth(t, auth)

	c.base.SendLog(fmt.Sprintf("Testing provided key for %s@%s", t.User, t.IP))
	if !c.testAndAddAuthentication(t, sshConfig) {
		return fmt.Errorf("Provided key for %s@%s failed to authenticate", t.User, t.IP)
	}
	c.base.SendLog(fmt.Sprintf("Key verified for %s@%s", t.User, t.IP))
	return nil
}
Beispiel #29
0
// LoadPKCS1PrivateKeyPEM load & parse private key from PEM-file
func LoadPKCS1PrivateKeyPEM(path, password string) (*rsa.PrivateKey, error) {
	bytes, err := ioutil.ReadFile(path)
	if err != nil {
		return nil, err
	}
	block, _ := pem.Decode(bytes)
	if block == nil {
		return nil, errors.New("Invalid key; no PEM data found")
	}
	if block.Type != "RSA PRIVATE KEY" {
		return nil, errors.New("Invalid key; no RSA PRIVATE KEY block")
	}
	var data []byte
	if !x509.IsEncryptedPEMBlock(block) {
		data = block.Bytes
	} else if data, err = x509.DecryptPEMBlock(block, []byte(password)); err != nil {
		return nil, err
	}
	return x509.ParsePKCS1PrivateKey(data)
}
Beispiel #30
0
// https://github.com/rapidloop/rtop/blob/ba5b35e964135d50e0babedf0bd69b2fcb5dbcb4/src/sshhelper.go#L100
func addKeyAuth(auths []ssh.AuthMethod, keypath string, keypassword string) ([]ssh.AuthMethod, error) {
	if len(keypath) == 0 {
		return auths, nil
	}

	// read the file
	pemBytes, err := ioutil.ReadFile(keypath)
	if err != nil {
		return auths, err
	}

	// get first pem block
	block, _ := pem.Decode(pemBytes)
	if block == nil {
		return auths, fmt.Errorf("no key found in %s", keypath)
	}

	// handle plain and encrypted keyfiles
	if x509.IsEncryptedPEMBlock(block) {
		block.Bytes, err = x509.DecryptPEMBlock(block, []byte(keypassword))
		if err != nil {
			return auths, err
		}
		key, err := parsePemBlock(block)
		if err != nil {
			return auths, err
		}
		signer, err := ssh.NewSignerFromKey(key)
		if err != nil {
			return auths, err
		}
		return append(auths, ssh.PublicKeys(signer)), nil
	}

	signer, err := ssh.ParsePrivateKey(pemBytes)
	if err != nil {
		return auths, err
	}
	return append(auths, ssh.PublicKeys(signer)), nil
}