Initial QSfera import

This commit is contained in:
Курнат Андрей
2026-06-07 10:20:04 +03:00
commit 2315f25754
16485 changed files with 4826827 additions and 0 deletions
+23
View File
@@ -0,0 +1,23 @@
Copyright 2014 Matthew Endsley
All rights reserved
Redistribution and use in source and binary forms, with or without
modification, are permitted providing that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
+25
View File
@@ -0,0 +1,25 @@
gojwk
=====
Golang implementation of JWK validation
Contact
-------
[@\_boblan\_](https://twitter.com/#!/_boblan_)
<https://github.com/mendsley/gojws>
License
-------
Copyright 2014 Matthew Endsley
This project is governed by the BSD 2-clause license. For details see the file
titled LICENSE in the project root folder.
Using
-----
Simply add the following import
`import "github.com/mendsley/gojwk"`
Documentation
-------------
See <http://godoc.org/github.com/mendsley/gojwk>
+44
View File
@@ -0,0 +1,44 @@
// Copyright 2014 Matthew Endsley
// All rights reserved
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted providing that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package gojwk
import (
"encoding/base64"
"strings"
)
func safeDecode(str string) ([]byte, error) {
lenMod4 := len(str) % 4
if lenMod4 > 0 {
str = str + strings.Repeat("=", 4-lenMod4)
}
return base64.URLEncoding.DecodeString(str)
}
func safeEncode(p []byte) string {
data := base64.URLEncoding.EncodeToString(p)
return strings.TrimRight(data, "=")
}
+287
View File
@@ -0,0 +1,287 @@
// Copyright 2014 Matthew Endsley
// All rights reserved
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted providing that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package gojwk
import (
"crypto"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rsa"
"encoding/binary"
"encoding/json"
"errors"
"fmt"
"math/big"
)
type Key struct {
Keys []*Key `json:"keys,omitempty"`
Kty string `json:"kty"`
Use string `json:"use,omitempty"`
Kid string `json:"kid,omitempty"`
Alg string `json:"alg,omitempty"`
Crv string `json:"crv,omitempty"`
X string `json:"x,omitempty"`
Y string `json:"y,omitempty"`
D string `json:"d,omitempty"`
N string `json:"n,omitempty"`
E string `json:"e,omitempty"`
K string `json:"k,omitempty"`
}
// Wrapper to unmarshal a JSON octet stream to a structured JWK
func Unmarshal(jwt []byte) (*Key, error) {
key := new(Key)
err := json.Unmarshal(jwt, key)
return key, err
}
// Wrapper to marshal a JSON octet stream from a structured JWK
func Marshal(key *Key) ([]byte, error) {
return json.Marshal(key)
}
// Create a JWK from a public key
func PublicKey(key crypto.PublicKey) (*Key, error) {
switch key := key.(type) {
case *rsa.PublicKey:
jwt := &Key{
Kty: "RSA",
N: safeEncode(key.N.Bytes()),
E: safeEncode(big.NewInt(int64(key.E)).Bytes()),
}
return jwt, nil
case *ecdsa.PublicKey:
jwt := &Key{
Kty: "EC",
X: safeEncode(key.X.Bytes()),
Y: safeEncode(key.Y.Bytes()),
}
switch key.Curve {
case elliptic.P224():
jwt.Crv = "P-224"
case elliptic.P256():
jwt.Crv = "P-256"
case elliptic.P384():
jwt.Crv = "P-384"
case elliptic.P521():
jwt.Crv = "P-521"
default:
return nil, fmt.Errorf("Unsupported ECDSA curve")
}
return jwt, nil
case []byte:
jwt := &Key{
Kty: "oct",
K: safeEncode(key),
}
return jwt, nil
default:
return nil, fmt.Errorf("Unknown key type %T", key)
}
}
// Create a JWK from a private key
func PrivateKey(key crypto.PrivateKey) (*Key, error) {
switch key := key.(type) {
case *rsa.PrivateKey:
jwt, err := PublicKey(&key.PublicKey)
if err != nil {
return nil, err
}
jwt.D = safeEncode(key.D.Bytes())
return jwt, err
case *ecdsa.PrivateKey:
jwt, err := PublicKey(&key.PublicKey)
if err != nil {
return nil, err
}
jwt.D = safeEncode(key.D.Bytes())
return jwt, nil
case []byte:
return PublicKey(key)
default:
return nil, fmt.Errorf("Unknown key type %T", key)
}
}
// Decode as a public key
func (key *Key) DecodePublicKey() (crypto.PublicKey, error) {
switch key.Kty {
case "RSA":
if key.N == "" || key.E == "" {
return nil, errors.New("Malformed JWK RSA key")
}
// decode exponent
data, err := safeDecode(key.E)
if err != nil {
return nil, errors.New("Malformed JWK RSA key")
}
if len(data) < 4 {
ndata := make([]byte, 4)
copy(ndata[4-len(data):], data)
data = ndata
}
pubKey := &rsa.PublicKey{
N: &big.Int{},
E: int(binary.BigEndian.Uint32(data[:])),
}
data, err = safeDecode(key.N)
if err != nil {
return nil, errors.New("Malformed JWK RSA key")
}
pubKey.N.SetBytes(data)
return pubKey, nil
case "EC":
if key.Crv == "" || key.X == "" || key.Y == "" {
return nil, errors.New("Malformed JWK EC key")
}
var curve elliptic.Curve
switch key.Crv {
case "P-224":
curve = elliptic.P224()
case "P-256":
curve = elliptic.P256()
case "P-384":
curve = elliptic.P384()
case "P-521":
curve = elliptic.P521()
default:
return nil, fmt.Errorf("Unknown curve type: %s", key.Crv)
}
pubKey := &ecdsa.PublicKey{
Curve: curve,
X: &big.Int{},
Y: &big.Int{},
}
data, err := safeDecode(key.X)
if err != nil {
return nil, fmt.Errorf("Malformed JWK EC key")
}
pubKey.X.SetBytes(data)
data, err = safeDecode(key.Y)
if err != nil {
return nil, fmt.Errorf("Malformed JWK EC key")
}
pubKey.Y.SetBytes(data)
return pubKey, nil
case "oct":
if key.K == "" {
return nil, errors.New("Malformed JWK octect key")
}
data, err := safeDecode(key.K)
if err != nil {
return nil, errors.New("Malformed JWK octect key")
}
return data, nil
default:
return nil, fmt.Errorf("Unknown JWK key type %s", key.Kty)
}
}
// Decodes as a private key
func (key *Key) DecodePrivateKey() (crypto.PrivateKey, error) {
switch key.Kty {
case "RSA":
if key.D == "" {
return nil, errors.New("Malformed JWK RSA key")
}
pub, err := key.DecodePublicKey()
if err != nil {
return nil, err
}
privKey := &rsa.PrivateKey{
PublicKey: *pub.(*rsa.PublicKey),
D: &big.Int{},
}
data, err := safeDecode(key.D)
if err != nil {
return nil, errors.New("Malformed JWK RSA key")
}
privKey.D.SetBytes(data)
return privKey, nil
case "EC":
if key.D == "" {
return nil, errors.New("Malformed JWK EC key")
}
pub, err := key.DecodePublicKey()
if err != nil {
return nil, err
}
privKey := &ecdsa.PrivateKey{
PublicKey: *pub.(*ecdsa.PublicKey),
D: &big.Int{},
}
data, err := safeDecode(key.D)
if err != nil {
return nil, fmt.Errorf("Malformed JWK EC key")
}
privKey.D.SetBytes(data)
return privKey, nil
case "oct":
return key.DecodePublicKey()
default:
return nil, fmt.Errorf("Unknown JWK key type %s", key.Kty)
}
}