Example #1
0
// ParsePrivateKeyPEM parses and returns a PEM-encoded private
// key. The private key may be either an unencrypted PKCS#8, PKCS#1,
// or elliptic private key.
func ParsePrivateKeyPEM(keyPEM []byte) (key crypto.Signer, err error) {
	keyDER, err := GetKeyDERFromPEM(keyPEM)
	if err != nil {
		return nil, err
	}

	return derhelpers.ParsePrivateKeyDER(keyDER)
}
Example #2
0
// LoadKey attempts to load a private key from PEM or DER.
func LoadKey(in []byte) (priv crypto.Signer, err error) {
	priv, err = helpers.ParsePrivateKeyPEM(in)
	if err == nil {
		return priv, nil
	}

	return derhelpers.ParsePrivateKeyDER(in)
}
Example #3
0
// Take in either two or one safeBags and return the certificates and or
// Private key within the bags
func parseBags(bags []safeBag, password []byte) (certs []*x509.Certificate, key crypto.Signer, err error) {
	for _, bag := range bags {
		bagid := bag.ID.String()
		switch bagid {
		case certBagID:
			var CertBag certBag
			if _, err = asn1.Unmarshal(bag.Value.Bytes, &CertBag); err != nil {
				return nil, nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err)
			}
			certs, err = x509.ParseCertificates(CertBag.Data)

			if err != nil {
				return nil, nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err)
			}

		case pkcs8ShroudedBagID:
			var pkinfo encryptedPrivateKeyInfo
			if _, err := asn1.Unmarshal(bag.Value.Bytes, &pkinfo); err != nil {
				return nil, nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err)
			}
			pkDecrypted, err := decrypt(pkinfo.AlgorithmIdentifier, pkinfo.EncryptedData, password)
			if err != nil {
				return nil, nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err)
			}
			// Checking if private key data has been properly decoded
			var rv asn1.RawValue
			if _, err = asn1.Unmarshal(pkDecrypted, &rv); err != nil {
				return nil, nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err)
			}
			if key, err = derhelpers.ParsePrivateKeyDER(pkDecrypted); err != nil {
				return nil, nil, err
			}

		default:
			return nil, nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, errors.New("Only support for certificate bags and PKCS #8 Shrouded Bags"))
		}
	}
	return certs, key, nil
}
Example #4
0
func parsePrivateKeySpec(spec string, cfg map[string]string) (crypto.Signer, error) {
	specURL, err := url.Parse(spec)
	if err != nil {
		return nil, err
	}

	var priv crypto.Signer
	switch specURL.Scheme {
	case "file":
		// A file spec will be parsed such that the root
		// directory of a relative path will be stored as the
		// hostname, and the remainder of the file's path is
		// stored in the Path field.
		log.Debug("loading private key file", specURL.Path)
		path := filepath.Join(specURL.Host, specURL.Path)
		in, err := ioutil.ReadFile(path)
		if err != nil {
			return nil, err
		}

		log.Debug("attempting to load PEM-encoded private key")
		priv, err = helpers.ParsePrivateKeyPEM(in)
		if err != nil {
			log.Debug("file is not a PEM-encoded private key")
			log.Debug("attempting to load DER-encoded private key")
			priv, err = derhelpers.ParsePrivateKeyDER(in)
			if err != nil {
				return nil, err
			}
		}
		log.Debug("loaded private key")
		return priv, nil
	case "rofile":
		log.Warning("Red October support is currently experimental")
		path := filepath.Join(specURL.Host, specURL.Path)
		in, err := ioutil.ReadFile(path)
		if err != nil {
			return nil, err
		}

		roServer := cfg["ro_server"]
		if roServer == "" {
			return nil, errors.New("config: no RedOctober server available")
		}

		// roCAPath can be empty; if it is, the client uses
		// the system default CA roots.
		roCAPath := cfg["ro_ca"]

		roUser := cfg["ro_user"]
		if roUser == "" {
			return nil, errors.New("config: no RedOctober user available")
		}

		roPass := cfg["ro_pass"]
		if roPass == "" {
			return nil, errors.New("config: no RedOctober passphrase available")
		}

		log.Debug("decrypting key via RedOctober Server")
		roClient, err := client.NewRemoteServer(roServer, roCAPath)
		if err != nil {
			return nil, err
		}

		req := core.DecryptRequest{
			Name:     roUser,
			Password: roPass,
			Data:     in,
		}
		in, err = roClient.DecryptIntoData(req)
		if err != nil {
			return nil, err
		}

		return priv, nil
	default:
		return nil, ErrUnsupportedScheme
	}
}