shared.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500
  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. package jose
  17. import (
  18. "crypto/elliptic"
  19. "crypto/x509"
  20. "encoding/base64"
  21. "errors"
  22. "fmt"
  23. "gopkg.in/square/go-jose.v2/json"
  24. )
  25. // KeyAlgorithm represents a key management algorithm.
  26. type KeyAlgorithm string
  27. // SignatureAlgorithm represents a signature (or MAC) algorithm.
  28. type SignatureAlgorithm string
  29. // ContentEncryption represents a content encryption algorithm.
  30. type ContentEncryption string
  31. // CompressionAlgorithm represents an algorithm used for plaintext compression.
  32. type CompressionAlgorithm string
  33. // ContentType represents type of the contained data.
  34. type ContentType string
  35. var (
  36. // ErrCryptoFailure represents an error in cryptographic primitive. This
  37. // occurs when, for example, a message had an invalid authentication tag or
  38. // could not be decrypted.
  39. ErrCryptoFailure = errors.New("square/go-jose: error in cryptographic primitive")
  40. // ErrUnsupportedAlgorithm indicates that a selected algorithm is not
  41. // supported. This occurs when trying to instantiate an encrypter for an
  42. // algorithm that is not yet implemented.
  43. ErrUnsupportedAlgorithm = errors.New("square/go-jose: unknown/unsupported algorithm")
  44. // ErrUnsupportedKeyType indicates that the given key type/format is not
  45. // supported. This occurs when trying to instantiate an encrypter and passing
  46. // it a key of an unrecognized type or with unsupported parameters, such as
  47. // an RSA private key with more than two primes.
  48. ErrUnsupportedKeyType = errors.New("square/go-jose: unsupported key type/format")
  49. // ErrInvalidKeySize indicates that the given key is not the correct size
  50. // for the selected algorithm. This can occur, for example, when trying to
  51. // encrypt with AES-256 but passing only a 128-bit key as input.
  52. ErrInvalidKeySize = errors.New("square/go-jose: invalid key size for algorithm")
  53. // ErrNotSupported serialization of object is not supported. This occurs when
  54. // trying to compact-serialize an object which can't be represented in
  55. // compact form.
  56. ErrNotSupported = errors.New("square/go-jose: compact serialization not supported for object")
  57. // ErrUnprotectedNonce indicates that while parsing a JWS or JWE object, a
  58. // nonce header parameter was included in an unprotected header object.
  59. ErrUnprotectedNonce = errors.New("square/go-jose: Nonce parameter included in unprotected header")
  60. )
  61. // Key management algorithms
  62. const (
  63. ED25519 = KeyAlgorithm("ED25519")
  64. RSA1_5 = KeyAlgorithm("RSA1_5") // RSA-PKCS1v1.5
  65. RSA_OAEP = KeyAlgorithm("RSA-OAEP") // RSA-OAEP-SHA1
  66. RSA_OAEP_256 = KeyAlgorithm("RSA-OAEP-256") // RSA-OAEP-SHA256
  67. A128KW = KeyAlgorithm("A128KW") // AES key wrap (128)
  68. A192KW = KeyAlgorithm("A192KW") // AES key wrap (192)
  69. A256KW = KeyAlgorithm("A256KW") // AES key wrap (256)
  70. DIRECT = KeyAlgorithm("dir") // Direct encryption
  71. ECDH_ES = KeyAlgorithm("ECDH-ES") // ECDH-ES
  72. ECDH_ES_A128KW = KeyAlgorithm("ECDH-ES+A128KW") // ECDH-ES + AES key wrap (128)
  73. ECDH_ES_A192KW = KeyAlgorithm("ECDH-ES+A192KW") // ECDH-ES + AES key wrap (192)
  74. ECDH_ES_A256KW = KeyAlgorithm("ECDH-ES+A256KW") // ECDH-ES + AES key wrap (256)
  75. A128GCMKW = KeyAlgorithm("A128GCMKW") // AES-GCM key wrap (128)
  76. A192GCMKW = KeyAlgorithm("A192GCMKW") // AES-GCM key wrap (192)
  77. A256GCMKW = KeyAlgorithm("A256GCMKW") // AES-GCM key wrap (256)
  78. PBES2_HS256_A128KW = KeyAlgorithm("PBES2-HS256+A128KW") // PBES2 + HMAC-SHA256 + AES key wrap (128)
  79. PBES2_HS384_A192KW = KeyAlgorithm("PBES2-HS384+A192KW") // PBES2 + HMAC-SHA384 + AES key wrap (192)
  80. PBES2_HS512_A256KW = KeyAlgorithm("PBES2-HS512+A256KW") // PBES2 + HMAC-SHA512 + AES key wrap (256)
  81. )
  82. // Signature algorithms
  83. const (
  84. EdDSA = SignatureAlgorithm("EdDSA")
  85. HS256 = SignatureAlgorithm("HS256") // HMAC using SHA-256
  86. HS384 = SignatureAlgorithm("HS384") // HMAC using SHA-384
  87. HS512 = SignatureAlgorithm("HS512") // HMAC using SHA-512
  88. RS256 = SignatureAlgorithm("RS256") // RSASSA-PKCS-v1.5 using SHA-256
  89. RS384 = SignatureAlgorithm("RS384") // RSASSA-PKCS-v1.5 using SHA-384
  90. RS512 = SignatureAlgorithm("RS512") // RSASSA-PKCS-v1.5 using SHA-512
  91. ES256 = SignatureAlgorithm("ES256") // ECDSA using P-256 and SHA-256
  92. ES384 = SignatureAlgorithm("ES384") // ECDSA using P-384 and SHA-384
  93. ES512 = SignatureAlgorithm("ES512") // ECDSA using P-521 and SHA-512
  94. PS256 = SignatureAlgorithm("PS256") // RSASSA-PSS using SHA256 and MGF1-SHA256
  95. PS384 = SignatureAlgorithm("PS384") // RSASSA-PSS using SHA384 and MGF1-SHA384
  96. PS512 = SignatureAlgorithm("PS512") // RSASSA-PSS using SHA512 and MGF1-SHA512
  97. )
  98. // Content encryption algorithms
  99. const (
  100. A128CBC_HS256 = ContentEncryption("A128CBC-HS256") // AES-CBC + HMAC-SHA256 (128)
  101. A192CBC_HS384 = ContentEncryption("A192CBC-HS384") // AES-CBC + HMAC-SHA384 (192)
  102. A256CBC_HS512 = ContentEncryption("A256CBC-HS512") // AES-CBC + HMAC-SHA512 (256)
  103. A128GCM = ContentEncryption("A128GCM") // AES-GCM (128)
  104. A192GCM = ContentEncryption("A192GCM") // AES-GCM (192)
  105. A256GCM = ContentEncryption("A256GCM") // AES-GCM (256)
  106. )
  107. // Compression algorithms
  108. const (
  109. NONE = CompressionAlgorithm("") // No compression
  110. DEFLATE = CompressionAlgorithm("DEF") // DEFLATE (RFC 1951)
  111. )
  112. // A key in the protected header of a JWS object. Use of the Header...
  113. // constants is preferred to enhance type safety.
  114. type HeaderKey string
  115. const (
  116. HeaderType HeaderKey = "typ" // string
  117. HeaderContentType = "cty" // string
  118. // These are set by go-jose and shouldn't need to be set by consumers of the
  119. // library.
  120. headerAlgorithm = "alg" // string
  121. headerEncryption = "enc" // ContentEncryption
  122. headerCompression = "zip" // CompressionAlgorithm
  123. headerCritical = "crit" // []string
  124. headerAPU = "apu" // *byteBuffer
  125. headerAPV = "apv" // *byteBuffer
  126. headerEPK = "epk" // *JSONWebKey
  127. headerIV = "iv" // *byteBuffer
  128. headerTag = "tag" // *byteBuffer
  129. headerX5c = "x5c" // []*x509.Certificate
  130. headerJWK = "jwk" // *JSONWebKey
  131. headerKeyID = "kid" // string
  132. headerNonce = "nonce" // string
  133. headerP2C = "p2c" // *byteBuffer (int)
  134. headerP2S = "p2s" // *byteBuffer ([]byte)
  135. )
  136. // rawHeader represents the JOSE header for JWE/JWS objects (used for parsing).
  137. //
  138. // The decoding of the constituent items is deferred because we want to marshal
  139. // some members into particular structs rather than generic maps, but at the
  140. // same time we need to receive any extra fields unhandled by this library to
  141. // pass through to consuming code in case it wants to examine them.
  142. type rawHeader map[HeaderKey]*json.RawMessage
  143. // Header represents the read-only JOSE header for JWE/JWS objects.
  144. type Header struct {
  145. KeyID string
  146. JSONWebKey *JSONWebKey
  147. Algorithm string
  148. Nonce string
  149. // Unverified certificate chain parsed from x5c header.
  150. certificates []*x509.Certificate
  151. // Any headers not recognised above get unmarshaled
  152. // from JSON in a generic manner and placed in this map.
  153. ExtraHeaders map[HeaderKey]interface{}
  154. }
  155. // Certificates verifies & returns the certificate chain present
  156. // in the x5c header field of a message, if one was present. Returns
  157. // an error if there was no x5c header present or the chain could
  158. // not be validated with the given verify options.
  159. func (h Header) Certificates(opts x509.VerifyOptions) ([][]*x509.Certificate, error) {
  160. if len(h.certificates) == 0 {
  161. return nil, errors.New("square/go-jose: no x5c header present in message")
  162. }
  163. leaf := h.certificates[0]
  164. if opts.Intermediates == nil {
  165. opts.Intermediates = x509.NewCertPool()
  166. for _, intermediate := range h.certificates[1:] {
  167. opts.Intermediates.AddCert(intermediate)
  168. }
  169. }
  170. return leaf.Verify(opts)
  171. }
  172. func (parsed rawHeader) set(k HeaderKey, v interface{}) error {
  173. b, err := json.Marshal(v)
  174. if err != nil {
  175. return err
  176. }
  177. parsed[k] = makeRawMessage(b)
  178. return nil
  179. }
  180. // getString gets a string from the raw JSON, defaulting to "".
  181. func (parsed rawHeader) getString(k HeaderKey) string {
  182. v, ok := parsed[k]
  183. if !ok || v == nil {
  184. return ""
  185. }
  186. var s string
  187. err := json.Unmarshal(*v, &s)
  188. if err != nil {
  189. return ""
  190. }
  191. return s
  192. }
  193. // getByteBuffer gets a byte buffer from the raw JSON. Returns (nil, nil) if
  194. // not specified.
  195. func (parsed rawHeader) getByteBuffer(k HeaderKey) (*byteBuffer, error) {
  196. v := parsed[k]
  197. if v == nil {
  198. return nil, nil
  199. }
  200. var bb *byteBuffer
  201. err := json.Unmarshal(*v, &bb)
  202. if err != nil {
  203. return nil, err
  204. }
  205. return bb, nil
  206. }
  207. // getAlgorithm extracts parsed "alg" from the raw JSON as a KeyAlgorithm.
  208. func (parsed rawHeader) getAlgorithm() KeyAlgorithm {
  209. return KeyAlgorithm(parsed.getString(headerAlgorithm))
  210. }
  211. // getSignatureAlgorithm extracts parsed "alg" from the raw JSON as a SignatureAlgorithm.
  212. func (parsed rawHeader) getSignatureAlgorithm() SignatureAlgorithm {
  213. return SignatureAlgorithm(parsed.getString(headerAlgorithm))
  214. }
  215. // getEncryption extracts parsed "enc" from the raw JSON.
  216. func (parsed rawHeader) getEncryption() ContentEncryption {
  217. return ContentEncryption(parsed.getString(headerEncryption))
  218. }
  219. // getCompression extracts parsed "zip" from the raw JSON.
  220. func (parsed rawHeader) getCompression() CompressionAlgorithm {
  221. return CompressionAlgorithm(parsed.getString(headerCompression))
  222. }
  223. func (parsed rawHeader) getNonce() string {
  224. return parsed.getString(headerNonce)
  225. }
  226. // getEPK extracts parsed "epk" from the raw JSON.
  227. func (parsed rawHeader) getEPK() (*JSONWebKey, error) {
  228. v := parsed[headerEPK]
  229. if v == nil {
  230. return nil, nil
  231. }
  232. var epk *JSONWebKey
  233. err := json.Unmarshal(*v, &epk)
  234. if err != nil {
  235. return nil, err
  236. }
  237. return epk, nil
  238. }
  239. // getAPU extracts parsed "apu" from the raw JSON.
  240. func (parsed rawHeader) getAPU() (*byteBuffer, error) {
  241. return parsed.getByteBuffer(headerAPU)
  242. }
  243. // getAPV extracts parsed "apv" from the raw JSON.
  244. func (parsed rawHeader) getAPV() (*byteBuffer, error) {
  245. return parsed.getByteBuffer(headerAPV)
  246. }
  247. // getIV extracts parsed "iv" frpom the raw JSON.
  248. func (parsed rawHeader) getIV() (*byteBuffer, error) {
  249. return parsed.getByteBuffer(headerIV)
  250. }
  251. // getTag extracts parsed "tag" frpom the raw JSON.
  252. func (parsed rawHeader) getTag() (*byteBuffer, error) {
  253. return parsed.getByteBuffer(headerTag)
  254. }
  255. // getJWK extracts parsed "jwk" from the raw JSON.
  256. func (parsed rawHeader) getJWK() (*JSONWebKey, error) {
  257. v := parsed[headerJWK]
  258. if v == nil {
  259. return nil, nil
  260. }
  261. var jwk *JSONWebKey
  262. err := json.Unmarshal(*v, &jwk)
  263. if err != nil {
  264. return nil, err
  265. }
  266. return jwk, nil
  267. }
  268. // getCritical extracts parsed "crit" from the raw JSON. If omitted, it
  269. // returns an empty slice.
  270. func (parsed rawHeader) getCritical() ([]string, error) {
  271. v := parsed[headerCritical]
  272. if v == nil {
  273. return nil, nil
  274. }
  275. var q []string
  276. err := json.Unmarshal(*v, &q)
  277. if err != nil {
  278. return nil, err
  279. }
  280. return q, nil
  281. }
  282. // getS2C extracts parsed "p2c" from the raw JSON.
  283. func (parsed rawHeader) getP2C() (int, error) {
  284. v := parsed[headerP2C]
  285. if v == nil {
  286. return 0, nil
  287. }
  288. var p2c int
  289. err := json.Unmarshal(*v, &p2c)
  290. if err != nil {
  291. return 0, err
  292. }
  293. return p2c, nil
  294. }
  295. // getS2S extracts parsed "p2s" from the raw JSON.
  296. func (parsed rawHeader) getP2S() (*byteBuffer, error) {
  297. return parsed.getByteBuffer(headerP2S)
  298. }
  299. // sanitized produces a cleaned-up header object from the raw JSON.
  300. func (parsed rawHeader) sanitized() (h Header, err error) {
  301. for k, v := range parsed {
  302. if v == nil {
  303. continue
  304. }
  305. switch k {
  306. case headerJWK:
  307. var jwk *JSONWebKey
  308. err = json.Unmarshal(*v, &jwk)
  309. if err != nil {
  310. err = fmt.Errorf("failed to unmarshal JWK: %v: %#v", err, string(*v))
  311. return
  312. }
  313. h.JSONWebKey = jwk
  314. case headerKeyID:
  315. var s string
  316. err = json.Unmarshal(*v, &s)
  317. if err != nil {
  318. err = fmt.Errorf("failed to unmarshal key ID: %v: %#v", err, string(*v))
  319. return
  320. }
  321. h.KeyID = s
  322. case headerAlgorithm:
  323. var s string
  324. err = json.Unmarshal(*v, &s)
  325. if err != nil {
  326. err = fmt.Errorf("failed to unmarshal algorithm: %v: %#v", err, string(*v))
  327. return
  328. }
  329. h.Algorithm = s
  330. case headerNonce:
  331. var s string
  332. err = json.Unmarshal(*v, &s)
  333. if err != nil {
  334. err = fmt.Errorf("failed to unmarshal nonce: %v: %#v", err, string(*v))
  335. return
  336. }
  337. h.Nonce = s
  338. case headerX5c:
  339. c := []string{}
  340. err = json.Unmarshal(*v, &c)
  341. if err != nil {
  342. err = fmt.Errorf("failed to unmarshal x5c header: %v: %#v", err, string(*v))
  343. return
  344. }
  345. h.certificates, err = parseCertificateChain(c)
  346. if err != nil {
  347. err = fmt.Errorf("failed to unmarshal x5c header: %v: %#v", err, string(*v))
  348. return
  349. }
  350. default:
  351. if h.ExtraHeaders == nil {
  352. h.ExtraHeaders = map[HeaderKey]interface{}{}
  353. }
  354. var v2 interface{}
  355. err = json.Unmarshal(*v, &v2)
  356. if err != nil {
  357. err = fmt.Errorf("failed to unmarshal value: %v: %#v", err, string(*v))
  358. return
  359. }
  360. h.ExtraHeaders[k] = v2
  361. }
  362. }
  363. return
  364. }
  365. func parseCertificateChain(chain []string) ([]*x509.Certificate, error) {
  366. out := make([]*x509.Certificate, len(chain))
  367. for i, cert := range chain {
  368. raw, err := base64.StdEncoding.DecodeString(cert)
  369. if err != nil {
  370. return nil, err
  371. }
  372. out[i], err = x509.ParseCertificate(raw)
  373. if err != nil {
  374. return nil, err
  375. }
  376. }
  377. return out, nil
  378. }
  379. func (dst rawHeader) isSet(k HeaderKey) bool {
  380. dvr := dst[k]
  381. if dvr == nil {
  382. return false
  383. }
  384. var dv interface{}
  385. err := json.Unmarshal(*dvr, &dv)
  386. if err != nil {
  387. return true
  388. }
  389. if dvStr, ok := dv.(string); ok {
  390. return dvStr != ""
  391. }
  392. return true
  393. }
  394. // Merge headers from src into dst, giving precedence to headers from l.
  395. func (dst rawHeader) merge(src *rawHeader) {
  396. if src == nil {
  397. return
  398. }
  399. for k, v := range *src {
  400. if dst.isSet(k) {
  401. continue
  402. }
  403. dst[k] = v
  404. }
  405. }
  406. // Get JOSE name of curve
  407. func curveName(crv elliptic.Curve) (string, error) {
  408. switch crv {
  409. case elliptic.P256():
  410. return "P-256", nil
  411. case elliptic.P384():
  412. return "P-384", nil
  413. case elliptic.P521():
  414. return "P-521", nil
  415. default:
  416. return "", fmt.Errorf("square/go-jose: unsupported/unknown elliptic curve")
  417. }
  418. }
  419. // Get size of curve in bytes
  420. func curveSize(crv elliptic.Curve) int {
  421. bits := crv.Params().BitSize
  422. div := bits / 8
  423. mod := bits % 8
  424. if mod == 0 {
  425. return div
  426. }
  427. return div + 1
  428. }
  429. func makeRawMessage(b []byte) *json.RawMessage {
  430. rm := json.RawMessage(b)
  431. return &rm
  432. }