Example #1
0
func encrypt(payload []byte, jwtHeader map[string]interface{}, key interface{}) (token string, err error) {
	var ok bool
	var keyMgmtAlg JwaAlgorithm
	var encAlg JweEncryption

	alg := jwtHeader["alg"].(string)
	enc := jwtHeader["enc"].(string)

	if keyMgmtAlg, ok = jwaAlgorithms[alg]; !ok {
		return "", errors.New(fmt.Sprintf("jwt.encrypt(): Unknown key management algorithm '%v'", alg))
	}

	if encAlg, ok = jweEncryptors[enc]; !ok {
		return "", errors.New(fmt.Sprintf("jwt.encrypt(): Unknown encryption algorithm '%v'", enc))
	}

	var cek, encryptedCek, header, iv, cipherText, authTag []byte

	if cek, encryptedCek, err = keyMgmtAlg.WrapNewKey(encAlg.KeySizeBits(), key, jwtHeader); err != nil {
		return "", err
	}

	if header, err = json.Marshal(jwtHeader); err != nil {
		return "", err
	}

	if iv, cipherText, authTag, err = encAlg.Encrypt([]byte(compact.Serialize(header)), payload, cek); err != nil {
		return "", err
	}

	return compact.Serialize(header, encryptedCek, iv, cipherText, authTag), nil
}
Example #2
0
// Sign produces signed JWT token given arbitrary payload, signature algorithm to use (see constants for list of supported algs) and signing key.
// Signing key is of different type for different signing alg, see specific
// signing alg implementation documentation.
//
// It returns 3 parts signed JWT token as string and not nil error if something went wrong.
func Sign(payload string, signingAlg string, key interface{}) (token string, err error) {
	if signer, ok := jwsHashers[signingAlg]; ok {

		jwtHeader := map[string]interface{}{
			"typ": "JWT",
			"alg": signingAlg,
		}

		paloadBytes := []byte(payload)
		var header []byte
		var signature []byte

		if header, err = json.Marshal(jwtHeader); err == nil {
			securedInput := []byte(compact.Serialize(header, paloadBytes))

			if signature, err = signer.Sign(securedInput, key); err == nil {
				return compact.Serialize(header, paloadBytes, signature), nil
			}
		}

		return "", err
	}

	return "", errors.New(fmt.Sprintf("jwt.Sign(): unknown algorithm: '%v'", signingAlg))
}
Example #3
0
// Sign produces signed JWT token given arbitrary payload, signature algorithm to use (see constants for list of supported algs), signing key and extra options (see option functions)
// Signing key is of different type for different signing alg, see specific
// signing alg implementation documentation.
//
// It returns 3 parts signed JWT token as string and not nil error if something went wrong.
func Sign(payload string, signingAlg string, key interface{}, options ...func(*joseConfig)) (token string, err error) {
	if signer, ok := jwsHashers[signingAlg]; ok {

		cfg := &joseConfig{compressionAlg: "", headers: make(map[string]interface{})}

		//apply extra options
		for _, option := range options {
			option(cfg)
		}

		//make sure defaults and requires are managed by us
		cfg.headers["alg"] = signingAlg

		if _, typ := cfg.headers["typ"]; !typ {
			cfg.headers["typ"] = "JWT"
		}

		paloadBytes := []byte(payload)
		var header []byte
		var signature []byte

		if header, err = json.Marshal(cfg.headers); err == nil {
			securedInput := []byte(compact.Serialize(header, paloadBytes))

			if signature, err = signer.Sign(securedInput, key); err == nil {
				return compact.Serialize(header, paloadBytes, signature), nil
			}
		}

		return "", err
	}

	return "", errors.New(fmt.Sprintf("jwt.Sign(): unknown algorithm: '%v'", signingAlg))
}
Example #4
0
func verify(parts [][]byte, key interface{}) (plainText string, headers map[string]interface{}, err error) {

	header, payload, signature := parts[0], parts[1], parts[2]

	secured := []byte(compact.Serialize(header, payload))

	var jwtHeader map[string]interface{}

	if err = json.Unmarshal(header, &jwtHeader); err != nil {
		return "", nil, err
	}

	alg := jwtHeader["alg"].(string)

	if verifier, ok := jwsHashers[alg]; ok {

		key = retrieveActualKey(jwtHeader, string(payload), key)

		if err = verifier.Verify(secured, signature, key); err == nil {
			return string(payload), jwtHeader, nil
		}

		return "", nil, err
	}

	return "", nil, errors.New(fmt.Sprintf("jwt.Decode(): Unknown algorithm: '%v'", alg))
}
Example #5
0
func decrypt(parts [][]byte, key interface{}) (plainText []byte, headers map[string]interface{}, err error) {

	header, encryptedCek, iv, cipherText, authTag := parts[0], parts[1], parts[2], parts[3], parts[4]

	var jwtHeader map[string]interface{}

	if e := json.Unmarshal(header, &jwtHeader); e != nil {
		return nil, nil, e
	}

	var keyMgmtAlg JwaAlgorithm
	var encAlg JweEncryption
	var zipAlg JwcAlgorithm
	var cek, plainBytes []byte
	var ok bool
	var alg, enc string

	if alg, ok = jwtHeader["alg"].(string); !ok {
		return nil, nil, errors.New(fmt.Sprint("jwt.Decode(): required 'alg' header is missing or of invalid type"))
	}

	if enc, ok = jwtHeader["enc"].(string); !ok {
		return nil, nil, errors.New(fmt.Sprint("jwt.Decode(): required 'enc' header is missing or of invalid type"))
	}

	aad := []byte(compact.Serialize(header))

	if keyMgmtAlg, ok = jwaAlgorithms[alg]; ok {
		if encAlg, ok = jweEncryptors[enc]; ok {

			if key, err = retrieveActualKey(jwtHeader, string(cipherText), key); err != nil {
				return nil, nil, err
			}

			if cek, err = keyMgmtAlg.Unwrap(encryptedCek, key, encAlg.KeySizeBits(), jwtHeader); err == nil {
				if plainBytes, err = encAlg.Decrypt(aad, cek, iv, cipherText, authTag); err == nil {

					if zip, compressed := jwtHeader["zip"].(string); compressed {

						if zipAlg, ok = jwcCompressors[zip]; !ok {
							return nil, nil, errors.New(fmt.Sprintf("jwt.decrypt(): Unknown compression algorithm '%v'", zip))
						}

						plainBytes = zipAlg.Decompress(plainBytes)
					}

					return plainBytes, jwtHeader, nil
				}

				return nil, nil, err
			}

			return nil, nil, err
		}

		return nil, nil, errors.New(fmt.Sprintf("jwt.decrypt(): Unknown encryption algorithm '%v'", enc))
	}

	return nil, nil, errors.New(fmt.Sprintf("jwt.decrypt(): Unknown key management algorithm '%v'", alg))
}
Example #6
0
func verify(parts [][]byte, key interface{}) (plainText []byte, headers map[string]interface{}, err error) {

	header, payload, signature := parts[0], parts[1], parts[2]

	secured := []byte(compact.Serialize(header, payload))

	var jwtHeader map[string]interface{}

	if err = json.Unmarshal(header, &jwtHeader); err != nil {
		return nil, nil, err
	}

	if alg, ok := jwtHeader["alg"].(string); ok {
		if verifier, ok := jwsHashers[alg]; ok {
			if key, err = retrieveActualKey(jwtHeader, string(payload), key); err != nil {
				return nil, nil, err
			}

			if err = verifier.Verify(secured, signature, key); err == nil {
				return payload, jwtHeader, nil
			}

			return nil, nil, err
		}

		return nil, nil, errors.New(fmt.Sprintf("jwt.Decode(): Unknown algorithm: '%v'", alg))
	}

	return nil, nil, errors.New(fmt.Sprint("jwt.Decode(): required 'alg' header is missing or of invalid type"))
}