Beispiel #1
0
func (h *EssentialHeader) Construct(m map[string]interface{}) error {
	r := emap.Hmap(m)
	if alg, err := r.GetString("alg"); err == nil {
		h.Algorithm = jwa.SignatureAlgorithm(alg)
	}
	if h.Algorithm == "" {
		h.Algorithm = jwa.NoSignature
	}
	h.ContentType, _ = r.GetString("cty")
	h.KeyID, _ = r.GetString("kid")
	h.Type, _ = r.GetString("typ")
	h.X509CertThumbprint, _ = r.GetString("x5t")
	h.X509CertThumbprintS256, _ = r.GetString("x5t#256")
	if v, err := r.GetStringSlice("crit"); err != nil {
		h.Critical = v
	}
	if v, err := r.GetStringSlice("x5c"); err != nil {
		h.X509CertChain = v
	}
	if v, err := r.GetString("jku"); err == nil {
		u, err := url.Parse(v)
		if err == nil {
			h.JwkSetURL = u
		}
	}

	if v, err := r.GetString("x5u"); err == nil {
		u, err := url.Parse(v)
		if err == nil {
			h.X509Url = u
		}
	}

	return nil
}
Beispiel #2
0
// VerifyWithJWK verifies the JWS message using JWK keys
func VerifyWithJWK(buf []byte, keyset *jwk.Set) ([]byte, error) {
	m, err := Parse(buf)
	if err != nil {
		return nil, err
	}

	for _, key := range keyset.Keys {
		if u := key.Use(); u != "" && u != "enc" {
			continue
		}

		keyval, err := key.Materialize()
		if err != nil {
			return nil, err
		}

		alg := jwa.SignatureAlgorithm(key.Alg())

		var verifier Verifier
		switch key.Kty() {
		case jwa.RSA:
			pubkey, ok := keyval.(*rsa.PublicKey)
			if !ok {
				return nil, errors.New("invalid key: *rsa.PublicKey is required")
			}
			verifier, err = NewRsaVerify(alg, pubkey)
			if err != nil {
				return nil, err
			}
		case jwa.EC:
			pubkey, ok := keyval.(*ecdsa.PublicKey)
			if !ok {
				return nil, errors.New("invalid key: *ecdsa.PublicKey is required")
			}
			verifier, err = NewEcdsaVerify(alg, pubkey)
			if err != nil {
				return nil, err
			}
		case jwa.OctetSeq:
			sharedkey, ok := keyval.([]byte)
			if !ok {
				return nil, errors.New("invalid key: []byte is required")
			}
			verifier, err = NewHmacVerify(alg, sharedkey)
			if err != nil {
				return nil, err
			}
		default:
			continue
		}

		if err := verifier.Verify(m); err != nil {
			continue
		}

		return m.Payload.Bytes(), nil
	}

	return nil, errors.New("failed to verify")
}
Beispiel #3
0
func verifyMessageWithJWK(m *Message, key jwk.Key) error {
	keyval, err := key.Materialize()
	if err != nil {
		return err
	}

	alg := jwa.SignatureAlgorithm(key.Alg())

	var verifier Verifier
	switch key.Kty() {
	case jwa.RSA:
		pubkey, ok := keyval.(*rsa.PublicKey)
		if !ok {
			return errors.New("invalid key: *rsa.PublicKey is required")
		}
		verifier, err = NewRsaVerify(alg, pubkey)
		if err != nil {
			return err
		}
	case jwa.EC:
		pubkey, ok := keyval.(*ecdsa.PublicKey)
		if !ok {
			return errors.New("invalid key: *ecdsa.PublicKey is required")
		}
		verifier, err = NewEcdsaVerify(alg, pubkey)
		if err != nil {
			return err
		}
	case jwa.OctetSeq:
		sharedkey, ok := keyval.([]byte)
		if !ok {
			return errors.New("invalid key: []byte is required")
		}
		verifier, err = NewHmacVerify(alg, sharedkey)
		if err != nil {
			return err
		}
	default:
		// don't know what this is...
		return errors.New("unknown signature algorithm")
	}

	if err := verifier.Verify(m); err != nil {
		// we return a stock "failed to verify" error so callers
		// can differentiate between other errors and Verify() failing
		// note: this masks potential errors within Verify(), but ... hmmm
		return errVerifyFailed
	}
	return nil
}
Beispiel #4
0
// Construct walks through the map (most likely parsed from a JSON buffer)
// and populates the necessary fields on this header
func (h *EssentialHeader) Construct(m map[string]interface{}) error {
	r := emap.Hmap(m)
	if alg, err := r.GetString("alg"); err == nil {
		h.Algorithm = jwa.SignatureAlgorithm(alg)
	}
	if h.Algorithm == "" {
		h.Algorithm = jwa.NoSignature
	}
	h.ContentType, _ = r.GetString("cty")
	h.KeyID, _ = r.GetString("kid")
	h.Type, _ = r.GetString("typ")
	h.X509CertThumbprint, _ = r.GetString("x5t")
	h.X509CertThumbprintS256, _ = r.GetString("x5t#256")
	if v, err := r.GetStringSlice("crit"); err != nil {
		h.Critical = v
	}
	if v, err := r.GetStringSlice("x5c"); err != nil {
		h.X509CertChain = v
	}
	if v, err := r.GetByteSlice("jwk"); err == nil {
		if jwks, err := jwk.Parse(v); err == nil {
			if len(jwks.Keys) != 1 {
				// The spec says "a JWK", so I believe this should represent
				// one JWK. check for that, and if not, return an error because
				// the JWS is probably invalid (XXX: send in a PR if there are
				// cases where this must work in the wild)
				return errors.New("expected a single JWK in this field")
			}
			h.Jwk = jwks.Keys[0]
		}
	}
	if v, err := r.GetString("jku"); err == nil {
		u, err := url.Parse(v)
		if err == nil {
			h.JwkSetURL = u
		}
	}

	if v, err := r.GetString("x5u"); err == nil {
		u, err := url.Parse(v)
		if err == nil {
			h.X509Url = u
		}
	}

	return nil
}
Beispiel #5
0
func (h *Header) Set(key string, value interface{}) error {
	switch key {
	case "alg":
		var v jwa.SignatureAlgorithm
		s, ok := value.(string)
		if ok {
			v = jwa.SignatureAlgorithm(s)
		} else {
			v, ok = value.(jwa.SignatureAlgorithm)
			if !ok {
				return ErrInvalidHeaderValue
			}
		}
		h.Algorithm = v
	case "cty":
		v, ok := value.(string)
		if !ok {
			return ErrInvalidHeaderValue
		}
		h.ContentType = v
	case "kid":
		v, ok := value.(string)
		if !ok {
			return ErrInvalidHeaderValue
		}
		h.KeyID = v
	case "typ":
		v, ok := value.(string)
		if !ok {
			return ErrInvalidHeaderValue
		}
		h.Type = v
	case "x5t":
		v, ok := value.(string)
		if !ok {
			return ErrInvalidHeaderValue
		}
		h.X509CertThumbprint = v
	case "x5t#256":
		v, ok := value.(string)
		if !ok {
			return ErrInvalidHeaderValue
		}
		h.X509CertThumbprintS256 = v
	case "x5c":
		v, ok := value.([]string)
		if !ok {
			return ErrInvalidHeaderValue
		}
		h.X509CertChain = v
	case "crit":
		v, ok := value.([]string)
		if !ok {
			return ErrInvalidHeaderValue
		}
		h.Critical = v
	case "jku":
		v, ok := value.(string)
		if !ok {
			return ErrInvalidHeaderValue
		}
		u, err := url.Parse(v)
		if err != nil {
			return ErrInvalidHeaderValue
		}
		h.JwkSetURL = u
	case "x5u":
		v, ok := value.(string)
		if !ok {
			return ErrInvalidHeaderValue
		}
		u, err := url.Parse(v)
		if err != nil {
			return ErrInvalidHeaderValue
		}
		h.X509Url = u
	default:
		h.PrivateParams[key] = value
	}
	return nil
}
Beispiel #6
0
func TestRsaSign_SignWithBadAlgorithm(t *testing.T) {
	_, err := NewRsaSign(jwa.SignatureAlgorithm("FooBar"), nil)
	if !assert.Equal(t, ErrUnsupportedAlgorithm, err, "Creating signer with unknown algorithm should return error") {
		return
	}
}