shared.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520
  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. headerB64 = "b64" // bool
  134. headerP2C = "p2c" // *byteBuffer (int)
  135. headerP2S = "p2s" // *byteBuffer ([]byte)
  136. )
  137. // supportedCritical is the set of supported extensions that are understood and processed.
  138. var supportedCritical = map[string]bool{
  139. headerB64: true,
  140. }
  141. // rawHeader represents the JOSE header for JWE/JWS objects (used for parsing).
  142. //
  143. // The decoding of the constituent items is deferred because we want to marshal
  144. // some members into particular structs rather than generic maps, but at the
  145. // same time we need to receive any extra fields unhandled by this library to
  146. // pass through to consuming code in case it wants to examine them.
  147. type rawHeader map[HeaderKey]*json.RawMessage
  148. // Header represents the read-only JOSE header for JWE/JWS objects.
  149. type Header struct {
  150. KeyID string
  151. JSONWebKey *JSONWebKey
  152. Algorithm string
  153. Nonce string
  154. // Unverified certificate chain parsed from x5c header.
  155. certificates []*x509.Certificate
  156. // Any headers not recognised above get unmarshaled
  157. // from JSON in a generic manner and placed in this map.
  158. ExtraHeaders map[HeaderKey]interface{}
  159. }
  160. // Certificates verifies & returns the certificate chain present
  161. // in the x5c header field of a message, if one was present. Returns
  162. // an error if there was no x5c header present or the chain could
  163. // not be validated with the given verify options.
  164. func (h Header) Certificates(opts x509.VerifyOptions) ([][]*x509.Certificate, error) {
  165. if len(h.certificates) == 0 {
  166. return nil, errors.New("square/go-jose: no x5c header present in message")
  167. }
  168. leaf := h.certificates[0]
  169. if opts.Intermediates == nil {
  170. opts.Intermediates = x509.NewCertPool()
  171. for _, intermediate := range h.certificates[1:] {
  172. opts.Intermediates.AddCert(intermediate)
  173. }
  174. }
  175. return leaf.Verify(opts)
  176. }
  177. func (parsed rawHeader) set(k HeaderKey, v interface{}) error {
  178. b, err := json.Marshal(v)
  179. if err != nil {
  180. return err
  181. }
  182. parsed[k] = makeRawMessage(b)
  183. return nil
  184. }
  185. // getString gets a string from the raw JSON, defaulting to "".
  186. func (parsed rawHeader) getString(k HeaderKey) string {
  187. v, ok := parsed[k]
  188. if !ok || v == nil {
  189. return ""
  190. }
  191. var s string
  192. err := json.Unmarshal(*v, &s)
  193. if err != nil {
  194. return ""
  195. }
  196. return s
  197. }
  198. // getByteBuffer gets a byte buffer from the raw JSON. Returns (nil, nil) if
  199. // not specified.
  200. func (parsed rawHeader) getByteBuffer(k HeaderKey) (*byteBuffer, error) {
  201. v := parsed[k]
  202. if v == nil {
  203. return nil, nil
  204. }
  205. var bb *byteBuffer
  206. err := json.Unmarshal(*v, &bb)
  207. if err != nil {
  208. return nil, err
  209. }
  210. return bb, nil
  211. }
  212. // getAlgorithm extracts parsed "alg" from the raw JSON as a KeyAlgorithm.
  213. func (parsed rawHeader) getAlgorithm() KeyAlgorithm {
  214. return KeyAlgorithm(parsed.getString(headerAlgorithm))
  215. }
  216. // getSignatureAlgorithm extracts parsed "alg" from the raw JSON as a SignatureAlgorithm.
  217. func (parsed rawHeader) getSignatureAlgorithm() SignatureAlgorithm {
  218. return SignatureAlgorithm(parsed.getString(headerAlgorithm))
  219. }
  220. // getEncryption extracts parsed "enc" from the raw JSON.
  221. func (parsed rawHeader) getEncryption() ContentEncryption {
  222. return ContentEncryption(parsed.getString(headerEncryption))
  223. }
  224. // getCompression extracts parsed "zip" from the raw JSON.
  225. func (parsed rawHeader) getCompression() CompressionAlgorithm {
  226. return CompressionAlgorithm(parsed.getString(headerCompression))
  227. }
  228. func (parsed rawHeader) getNonce() string {
  229. return parsed.getString(headerNonce)
  230. }
  231. // getEPK extracts parsed "epk" from the raw JSON.
  232. func (parsed rawHeader) getEPK() (*JSONWebKey, error) {
  233. v := parsed[headerEPK]
  234. if v == nil {
  235. return nil, nil
  236. }
  237. var epk *JSONWebKey
  238. err := json.Unmarshal(*v, &epk)
  239. if err != nil {
  240. return nil, err
  241. }
  242. return epk, nil
  243. }
  244. // getAPU extracts parsed "apu" from the raw JSON.
  245. func (parsed rawHeader) getAPU() (*byteBuffer, error) {
  246. return parsed.getByteBuffer(headerAPU)
  247. }
  248. // getAPV extracts parsed "apv" from the raw JSON.
  249. func (parsed rawHeader) getAPV() (*byteBuffer, error) {
  250. return parsed.getByteBuffer(headerAPV)
  251. }
  252. // getIV extracts parsed "iv" frpom the raw JSON.
  253. func (parsed rawHeader) getIV() (*byteBuffer, error) {
  254. return parsed.getByteBuffer(headerIV)
  255. }
  256. // getTag extracts parsed "tag" frpom the raw JSON.
  257. func (parsed rawHeader) getTag() (*byteBuffer, error) {
  258. return parsed.getByteBuffer(headerTag)
  259. }
  260. // getJWK extracts parsed "jwk" from the raw JSON.
  261. func (parsed rawHeader) getJWK() (*JSONWebKey, error) {
  262. v := parsed[headerJWK]
  263. if v == nil {
  264. return nil, nil
  265. }
  266. var jwk *JSONWebKey
  267. err := json.Unmarshal(*v, &jwk)
  268. if err != nil {
  269. return nil, err
  270. }
  271. return jwk, nil
  272. }
  273. // getCritical extracts parsed "crit" from the raw JSON. If omitted, it
  274. // returns an empty slice.
  275. func (parsed rawHeader) getCritical() ([]string, error) {
  276. v := parsed[headerCritical]
  277. if v == nil {
  278. return nil, nil
  279. }
  280. var q []string
  281. err := json.Unmarshal(*v, &q)
  282. if err != nil {
  283. return nil, err
  284. }
  285. return q, nil
  286. }
  287. // getS2C extracts parsed "p2c" from the raw JSON.
  288. func (parsed rawHeader) getP2C() (int, error) {
  289. v := parsed[headerP2C]
  290. if v == nil {
  291. return 0, nil
  292. }
  293. var p2c int
  294. err := json.Unmarshal(*v, &p2c)
  295. if err != nil {
  296. return 0, err
  297. }
  298. return p2c, nil
  299. }
  300. // getS2S extracts parsed "p2s" from the raw JSON.
  301. func (parsed rawHeader) getP2S() (*byteBuffer, error) {
  302. return parsed.getByteBuffer(headerP2S)
  303. }
  304. // getB64 extracts parsed "b64" from the raw JSON, defaulting to true.
  305. func (parsed rawHeader) getB64() (bool, error) {
  306. v := parsed[headerB64]
  307. if v == nil {
  308. return true, nil
  309. }
  310. var b64 bool
  311. err := json.Unmarshal(*v, &b64)
  312. if err != nil {
  313. return true, err
  314. }
  315. return b64, nil
  316. }
  317. // sanitized produces a cleaned-up header object from the raw JSON.
  318. func (parsed rawHeader) sanitized() (h Header, err error) {
  319. for k, v := range parsed {
  320. if v == nil {
  321. continue
  322. }
  323. switch k {
  324. case headerJWK:
  325. var jwk *JSONWebKey
  326. err = json.Unmarshal(*v, &jwk)
  327. if err != nil {
  328. err = fmt.Errorf("failed to unmarshal JWK: %v: %#v", err, string(*v))
  329. return
  330. }
  331. h.JSONWebKey = jwk
  332. case headerKeyID:
  333. var s string
  334. err = json.Unmarshal(*v, &s)
  335. if err != nil {
  336. err = fmt.Errorf("failed to unmarshal key ID: %v: %#v", err, string(*v))
  337. return
  338. }
  339. h.KeyID = s
  340. case headerAlgorithm:
  341. var s string
  342. err = json.Unmarshal(*v, &s)
  343. if err != nil {
  344. err = fmt.Errorf("failed to unmarshal algorithm: %v: %#v", err, string(*v))
  345. return
  346. }
  347. h.Algorithm = s
  348. case headerNonce:
  349. var s string
  350. err = json.Unmarshal(*v, &s)
  351. if err != nil {
  352. err = fmt.Errorf("failed to unmarshal nonce: %v: %#v", err, string(*v))
  353. return
  354. }
  355. h.Nonce = s
  356. case headerX5c:
  357. c := []string{}
  358. err = json.Unmarshal(*v, &c)
  359. if err != nil {
  360. err = fmt.Errorf("failed to unmarshal x5c header: %v: %#v", err, string(*v))
  361. return
  362. }
  363. h.certificates, err = parseCertificateChain(c)
  364. if err != nil {
  365. err = fmt.Errorf("failed to unmarshal x5c header: %v: %#v", err, string(*v))
  366. return
  367. }
  368. default:
  369. if h.ExtraHeaders == nil {
  370. h.ExtraHeaders = map[HeaderKey]interface{}{}
  371. }
  372. var v2 interface{}
  373. err = json.Unmarshal(*v, &v2)
  374. if err != nil {
  375. err = fmt.Errorf("failed to unmarshal value: %v: %#v", err, string(*v))
  376. return
  377. }
  378. h.ExtraHeaders[k] = v2
  379. }
  380. }
  381. return
  382. }
  383. func parseCertificateChain(chain []string) ([]*x509.Certificate, error) {
  384. out := make([]*x509.Certificate, len(chain))
  385. for i, cert := range chain {
  386. raw, err := base64.StdEncoding.DecodeString(cert)
  387. if err != nil {
  388. return nil, err
  389. }
  390. out[i], err = x509.ParseCertificate(raw)
  391. if err != nil {
  392. return nil, err
  393. }
  394. }
  395. return out, nil
  396. }
  397. func (dst rawHeader) isSet(k HeaderKey) bool {
  398. dvr := dst[k]
  399. if dvr == nil {
  400. return false
  401. }
  402. var dv interface{}
  403. err := json.Unmarshal(*dvr, &dv)
  404. if err != nil {
  405. return true
  406. }
  407. if dvStr, ok := dv.(string); ok {
  408. return dvStr != ""
  409. }
  410. return true
  411. }
  412. // Merge headers from src into dst, giving precedence to headers from l.
  413. func (dst rawHeader) merge(src *rawHeader) {
  414. if src == nil {
  415. return
  416. }
  417. for k, v := range *src {
  418. if dst.isSet(k) {
  419. continue
  420. }
  421. dst[k] = v
  422. }
  423. }
  424. // Get JOSE name of curve
  425. func curveName(crv elliptic.Curve) (string, error) {
  426. switch crv {
  427. case elliptic.P256():
  428. return "P-256", nil
  429. case elliptic.P384():
  430. return "P-384", nil
  431. case elliptic.P521():
  432. return "P-521", nil
  433. default:
  434. return "", fmt.Errorf("square/go-jose: unsupported/unknown elliptic curve")
  435. }
  436. }
  437. // Get size of curve in bytes
  438. func curveSize(crv elliptic.Curve) int {
  439. bits := crv.Params().BitSize
  440. div := bits / 8
  441. mod := bits % 8
  442. if mod == 0 {
  443. return div
  444. }
  445. return div + 1
  446. }
  447. func makeRawMessage(b []byte) *json.RawMessage {
  448. rm := json.RawMessage(b)
  449. return &rm
  450. }