1/*- 2 * Copyright 2014 Square Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package jose 18 19import ( 20 "crypto/elliptic" 21 "errors" 22 "fmt" 23) 24 25// KeyAlgorithm represents a key management algorithm. 26type KeyAlgorithm string 27 28// SignatureAlgorithm represents a signature (or MAC) algorithm. 29type SignatureAlgorithm string 30 31// ContentEncryption represents a content encryption algorithm. 32type ContentEncryption string 33 34// CompressionAlgorithm represents an algorithm used for plaintext compression. 35type CompressionAlgorithm string 36 37var ( 38 // ErrCryptoFailure represents an error in cryptographic primitive. This 39 // occurs when, for example, a message had an invalid authentication tag or 40 // could not be decrypted. 41 ErrCryptoFailure = errors.New("square/go-jose: error in cryptographic primitive") 42 43 // ErrUnsupportedAlgorithm indicates that a selected algorithm is not 44 // supported. This occurs when trying to instantiate an encrypter for an 45 // algorithm that is not yet implemented. 46 ErrUnsupportedAlgorithm = errors.New("square/go-jose: unknown/unsupported algorithm") 47 48 // ErrUnsupportedKeyType indicates that the given key type/format is not 49 // supported. This occurs when trying to instantiate an encrypter and passing 50 // it a key of an unrecognized type or with unsupported parameters, such as 51 // an RSA private key with more than two primes. 52 ErrUnsupportedKeyType = errors.New("square/go-jose: unsupported key type/format") 53 54 // ErrNotSupported serialization of object is not supported. This occurs when 55 // trying to compact-serialize an object which can't be represented in 56 // compact form. 57 ErrNotSupported = errors.New("square/go-jose: compact serialization not supported for object") 58 59 // ErrUnprotectedNonce indicates that while parsing a JWS or JWE object, a 60 // nonce header parameter was included in an unprotected header object. 61 ErrUnprotectedNonce = errors.New("square/go-jose: Nonce parameter included in unprotected header") 62) 63 64// Key management algorithms 65const ( 66 RSA1_5 = KeyAlgorithm("RSA1_5") // RSA-PKCS1v1.5 67 RSA_OAEP = KeyAlgorithm("RSA-OAEP") // RSA-OAEP-SHA1 68 RSA_OAEP_256 = KeyAlgorithm("RSA-OAEP-256") // RSA-OAEP-SHA256 69 A128KW = KeyAlgorithm("A128KW") // AES key wrap (128) 70 A192KW = KeyAlgorithm("A192KW") // AES key wrap (192) 71 A256KW = KeyAlgorithm("A256KW") // AES key wrap (256) 72 DIRECT = KeyAlgorithm("dir") // Direct encryption 73 ECDH_ES = KeyAlgorithm("ECDH-ES") // ECDH-ES 74 ECDH_ES_A128KW = KeyAlgorithm("ECDH-ES+A128KW") // ECDH-ES + AES key wrap (128) 75 ECDH_ES_A192KW = KeyAlgorithm("ECDH-ES+A192KW") // ECDH-ES + AES key wrap (192) 76 ECDH_ES_A256KW = KeyAlgorithm("ECDH-ES+A256KW") // ECDH-ES + AES key wrap (256) 77 A128GCMKW = KeyAlgorithm("A128GCMKW") // AES-GCM key wrap (128) 78 A192GCMKW = KeyAlgorithm("A192GCMKW") // AES-GCM key wrap (192) 79 A256GCMKW = KeyAlgorithm("A256GCMKW") // AES-GCM key wrap (256) 80 PBES2_HS256_A128KW = KeyAlgorithm("PBES2-HS256+A128KW") // PBES2 + HMAC-SHA256 + AES key wrap (128) 81 PBES2_HS384_A192KW = KeyAlgorithm("PBES2-HS384+A192KW") // PBES2 + HMAC-SHA384 + AES key wrap (192) 82 PBES2_HS512_A256KW = KeyAlgorithm("PBES2-HS512+A256KW") // PBES2 + HMAC-SHA512 + AES key wrap (256) 83) 84 85// Signature algorithms 86const ( 87 HS256 = SignatureAlgorithm("HS256") // HMAC using SHA-256 88 HS384 = SignatureAlgorithm("HS384") // HMAC using SHA-384 89 HS512 = SignatureAlgorithm("HS512") // HMAC using SHA-512 90 RS256 = SignatureAlgorithm("RS256") // RSASSA-PKCS-v1.5 using SHA-256 91 RS384 = SignatureAlgorithm("RS384") // RSASSA-PKCS-v1.5 using SHA-384 92 RS512 = SignatureAlgorithm("RS512") // RSASSA-PKCS-v1.5 using SHA-512 93 ES256 = SignatureAlgorithm("ES256") // ECDSA using P-256 and SHA-256 94 ES384 = SignatureAlgorithm("ES384") // ECDSA using P-384 and SHA-384 95 ES512 = SignatureAlgorithm("ES512") // ECDSA using P-521 and SHA-512 96 PS256 = SignatureAlgorithm("PS256") // RSASSA-PSS using SHA256 and MGF1-SHA256 97 PS384 = SignatureAlgorithm("PS384") // RSASSA-PSS using SHA384 and MGF1-SHA384 98 PS512 = SignatureAlgorithm("PS512") // RSASSA-PSS using SHA512 and MGF1-SHA512 99) 100 101// Content encryption algorithms 102const ( 103 A128CBC_HS256 = ContentEncryption("A128CBC-HS256") // AES-CBC + HMAC-SHA256 (128) 104 A192CBC_HS384 = ContentEncryption("A192CBC-HS384") // AES-CBC + HMAC-SHA384 (192) 105 A256CBC_HS512 = ContentEncryption("A256CBC-HS512") // AES-CBC + HMAC-SHA512 (256) 106 A128GCM = ContentEncryption("A128GCM") // AES-GCM (128) 107 A192GCM = ContentEncryption("A192GCM") // AES-GCM (192) 108 A256GCM = ContentEncryption("A256GCM") // AES-GCM (256) 109) 110 111// Compression algorithms 112const ( 113 NONE = CompressionAlgorithm("") // No compression 114 DEFLATE = CompressionAlgorithm("DEF") // DEFLATE (RFC 1951) 115) 116 117// rawHeader represents the JOSE header for JWE/JWS objects (used for parsing). 118type rawHeader struct { 119 Alg string `json:"alg,omitempty"` 120 Enc ContentEncryption `json:"enc,omitempty"` 121 Zip CompressionAlgorithm `json:"zip,omitempty"` 122 Crit []string `json:"crit,omitempty"` 123 Apu *byteBuffer `json:"apu,omitempty"` 124 Apv *byteBuffer `json:"apv,omitempty"` 125 Epk *JsonWebKey `json:"epk,omitempty"` 126 Iv *byteBuffer `json:"iv,omitempty"` 127 Tag *byteBuffer `json:"tag,omitempty"` 128 Jwk *JsonWebKey `json:"jwk,omitempty"` 129 Kid string `json:"kid,omitempty"` 130 Nonce string `json:"nonce,omitempty"` 131} 132 133// JoseHeader represents the read-only JOSE header for JWE/JWS objects. 134type JoseHeader struct { 135 KeyID string 136 JsonWebKey *JsonWebKey 137 Algorithm string 138 Nonce string 139} 140 141// sanitized produces a cleaned-up header object from the raw JSON. 142func (parsed rawHeader) sanitized() JoseHeader { 143 return JoseHeader{ 144 KeyID: parsed.Kid, 145 JsonWebKey: parsed.Jwk, 146 Algorithm: parsed.Alg, 147 Nonce: parsed.Nonce, 148 } 149} 150 151// Merge headers from src into dst, giving precedence to headers from l. 152func (dst *rawHeader) merge(src *rawHeader) { 153 if src == nil { 154 return 155 } 156 157 if dst.Alg == "" { 158 dst.Alg = src.Alg 159 } 160 if dst.Enc == "" { 161 dst.Enc = src.Enc 162 } 163 if dst.Zip == "" { 164 dst.Zip = src.Zip 165 } 166 if dst.Crit == nil { 167 dst.Crit = src.Crit 168 } 169 if dst.Crit == nil { 170 dst.Crit = src.Crit 171 } 172 if dst.Apu == nil { 173 dst.Apu = src.Apu 174 } 175 if dst.Apv == nil { 176 dst.Apv = src.Apv 177 } 178 if dst.Epk == nil { 179 dst.Epk = src.Epk 180 } 181 if dst.Iv == nil { 182 dst.Iv = src.Iv 183 } 184 if dst.Tag == nil { 185 dst.Tag = src.Tag 186 } 187 if dst.Kid == "" { 188 dst.Kid = src.Kid 189 } 190 if dst.Jwk == nil { 191 dst.Jwk = src.Jwk 192 } 193 if dst.Nonce == "" { 194 dst.Nonce = src.Nonce 195 } 196} 197 198// Get JOSE name of curve 199func curveName(crv elliptic.Curve) (string, error) { 200 switch crv { 201 case elliptic.P256(): 202 return "P-256", nil 203 case elliptic.P384(): 204 return "P-384", nil 205 case elliptic.P521(): 206 return "P-521", nil 207 default: 208 return "", fmt.Errorf("square/go-jose: unsupported/unknown elliptic curve") 209 } 210} 211 212// Get size of curve in bytes 213func curveSize(crv elliptic.Curve) int { 214 bits := crv.Params().BitSize 215 216 div := bits / 8 217 mod := bits % 8 218 219 if mod == 0 { 220 return div 221 } 222 223 return div + 1 224} 225