certs.go 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. // Copyright 2012 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package ssh
  5. import (
  6. "time"
  7. )
  8. // These constants from [PROTOCOL.certkeys] represent the algorithm names
  9. // for certificate types supported by this package.
  10. const (
  11. CertAlgoRSAv01 = "ssh-rsa-cert-v01@openssh.com"
  12. CertAlgoDSAv01 = "ssh-dss-cert-v01@openssh.com"
  13. CertAlgoECDSA256v01 = "ecdsa-sha2-nistp256-cert-v01@openssh.com"
  14. CertAlgoECDSA384v01 = "ecdsa-sha2-nistp384-cert-v01@openssh.com"
  15. CertAlgoECDSA521v01 = "ecdsa-sha2-nistp521-cert-v01@openssh.com"
  16. )
  17. // Certificate types are used to specify whether a certificate is for identification
  18. // of a user or a host. Current identities are defined in [PROTOCOL.certkeys].
  19. const (
  20. UserCert = 1
  21. HostCert = 2
  22. )
  23. type signature struct {
  24. Format string
  25. Blob []byte
  26. }
  27. type tuple struct {
  28. Name string
  29. Data string
  30. }
  31. // An OpenSSHCertV01 represents an OpenSSH certificate as defined in
  32. // [PROTOCOL.certkeys]?rev=1.8.
  33. type OpenSSHCertV01 struct {
  34. Nonce []byte
  35. Key PublicKey
  36. Serial uint64
  37. Type uint32
  38. KeyId string
  39. ValidPrincipals []string
  40. ValidAfter, ValidBefore time.Time
  41. CriticalOptions []tuple
  42. Extensions []tuple
  43. Reserved []byte
  44. SignatureKey PublicKey
  45. Signature *signature
  46. }
  47. var certAlgoNames = map[string]string{
  48. KeyAlgoRSA: CertAlgoRSAv01,
  49. KeyAlgoDSA: CertAlgoDSAv01,
  50. KeyAlgoECDSA256: CertAlgoECDSA256v01,
  51. KeyAlgoECDSA384: CertAlgoECDSA384v01,
  52. KeyAlgoECDSA521: CertAlgoECDSA521v01,
  53. }
  54. // certToPrivAlgo returns the underlying algorithm for a certificate algorithm.
  55. // Panics if a non-certificate algorithm is passed.
  56. func certToPrivAlgo(algo string) string {
  57. for privAlgo, pubAlgo := range certAlgoNames {
  58. if pubAlgo == algo {
  59. return privAlgo
  60. }
  61. }
  62. panic("unknown cert algorithm")
  63. }
  64. func (c *OpenSSHCertV01) PublicKeyAlgo() string {
  65. algo, ok := certAlgoNames[c.Key.PublicKeyAlgo()]
  66. if !ok {
  67. panic("unknown cert key type")
  68. }
  69. return algo
  70. }
  71. func (c *OpenSSHCertV01) PrivateKeyAlgo() string {
  72. return c.Key.PrivateKeyAlgo()
  73. }
  74. func (c *OpenSSHCertV01) Verify(data []byte, sig []byte) bool {
  75. return c.Key.Verify(data, sig)
  76. }
  77. func parseOpenSSHCertV01(in []byte, algo string) (out *OpenSSHCertV01, rest []byte, ok bool) {
  78. cert := new(OpenSSHCertV01)
  79. if cert.Nonce, in, ok = parseString(in); !ok {
  80. return
  81. }
  82. privAlgo := certToPrivAlgo(algo)
  83. cert.Key, in, ok = parsePubKey(in, privAlgo)
  84. if !ok {
  85. return
  86. }
  87. // We test PublicKeyAlgo to make sure we don't use some weird sub-cert.
  88. if cert.Key.PublicKeyAlgo() != privAlgo {
  89. ok = false
  90. return
  91. }
  92. if cert.Serial, in, ok = parseUint64(in); !ok {
  93. return
  94. }
  95. if cert.Type, in, ok = parseUint32(in); !ok || cert.Type != UserCert && cert.Type != HostCert {
  96. return
  97. }
  98. keyId, in, ok := parseString(in)
  99. if !ok {
  100. return
  101. }
  102. cert.KeyId = string(keyId)
  103. if cert.ValidPrincipals, in, ok = parseLengthPrefixedNameList(in); !ok {
  104. return
  105. }
  106. va, in, ok := parseUint64(in)
  107. if !ok {
  108. return
  109. }
  110. cert.ValidAfter = time.Unix(int64(va), 0)
  111. vb, in, ok := parseUint64(in)
  112. if !ok {
  113. return
  114. }
  115. cert.ValidBefore = time.Unix(int64(vb), 0)
  116. if cert.CriticalOptions, in, ok = parseTupleList(in); !ok {
  117. return
  118. }
  119. if cert.Extensions, in, ok = parseTupleList(in); !ok {
  120. return
  121. }
  122. if cert.Reserved, in, ok = parseString(in); !ok {
  123. return
  124. }
  125. sigKey, in, ok := parseString(in)
  126. if !ok {
  127. return
  128. }
  129. if cert.SignatureKey, _, ok = ParsePublicKey(sigKey); !ok {
  130. return
  131. }
  132. if cert.Signature, in, ok = parseSignature(in); !ok {
  133. return
  134. }
  135. ok = true
  136. return cert, in, ok
  137. }
  138. func (cert *OpenSSHCertV01) Marshal() []byte {
  139. pubKey := cert.Key.Marshal()
  140. sigKey := MarshalPublicKey(cert.SignatureKey)
  141. length := stringLength(len(cert.Nonce))
  142. length += len(pubKey)
  143. length += 8 // Length of Serial
  144. length += 4 // Length of Type
  145. length += stringLength(len(cert.KeyId))
  146. length += lengthPrefixedNameListLength(cert.ValidPrincipals)
  147. length += 8 // Length of ValidAfter
  148. length += 8 // Length of ValidBefore
  149. length += tupleListLength(cert.CriticalOptions)
  150. length += tupleListLength(cert.Extensions)
  151. length += stringLength(len(cert.Reserved))
  152. length += stringLength(len(sigKey))
  153. length += signatureLength(cert.Signature)
  154. ret := make([]byte, length)
  155. r := marshalString(ret, cert.Nonce)
  156. copy(r, pubKey)
  157. r = r[len(pubKey):]
  158. r = marshalUint64(r, cert.Serial)
  159. r = marshalUint32(r, cert.Type)
  160. r = marshalString(r, []byte(cert.KeyId))
  161. r = marshalLengthPrefixedNameList(r, cert.ValidPrincipals)
  162. r = marshalUint64(r, uint64(cert.ValidAfter.Unix()))
  163. r = marshalUint64(r, uint64(cert.ValidBefore.Unix()))
  164. r = marshalTupleList(r, cert.CriticalOptions)
  165. r = marshalTupleList(r, cert.Extensions)
  166. r = marshalString(r, cert.Reserved)
  167. r = marshalString(r, sigKey)
  168. r = marshalSignature(r, cert.Signature)
  169. if len(r) > 0 {
  170. panic("internal error")
  171. }
  172. return ret
  173. }
  174. func lengthPrefixedNameListLength(namelist []string) int {
  175. length := 4 // length prefix for list
  176. for _, name := range namelist {
  177. length += 4 // length prefix for name
  178. length += len(name)
  179. }
  180. return length
  181. }
  182. func marshalLengthPrefixedNameList(to []byte, namelist []string) []byte {
  183. length := uint32(lengthPrefixedNameListLength(namelist) - 4)
  184. to = marshalUint32(to, length)
  185. for _, name := range namelist {
  186. to = marshalString(to, []byte(name))
  187. }
  188. return to
  189. }
  190. func parseLengthPrefixedNameList(in []byte) (out []string, rest []byte, ok bool) {
  191. list, rest, ok := parseString(in)
  192. if !ok {
  193. return
  194. }
  195. for len(list) > 0 {
  196. var next []byte
  197. if next, list, ok = parseString(list); !ok {
  198. return nil, nil, false
  199. }
  200. out = append(out, string(next))
  201. }
  202. ok = true
  203. return
  204. }
  205. func tupleListLength(tupleList []tuple) int {
  206. length := 4 // length prefix for list
  207. for _, t := range tupleList {
  208. length += 4 // length prefix for t.Name
  209. length += len(t.Name)
  210. length += 4 // length prefix for t.Data
  211. length += len(t.Data)
  212. }
  213. return length
  214. }
  215. func marshalTupleList(to []byte, tuplelist []tuple) []byte {
  216. length := uint32(tupleListLength(tuplelist) - 4)
  217. to = marshalUint32(to, length)
  218. for _, t := range tuplelist {
  219. to = marshalString(to, []byte(t.Name))
  220. to = marshalString(to, []byte(t.Data))
  221. }
  222. return to
  223. }
  224. func parseTupleList(in []byte) (out []tuple, rest []byte, ok bool) {
  225. list, rest, ok := parseString(in)
  226. if !ok {
  227. return
  228. }
  229. for len(list) > 0 {
  230. var name, data []byte
  231. var ok bool
  232. name, list, ok = parseString(list)
  233. if !ok {
  234. return nil, nil, false
  235. }
  236. data, list, ok = parseString(list)
  237. if !ok {
  238. return nil, nil, false
  239. }
  240. out = append(out, tuple{string(name), string(data)})
  241. }
  242. ok = true
  243. return
  244. }
  245. func signatureLength(sig *signature) int {
  246. length := 4 // length prefix for signature
  247. length += stringLength(len(sig.Format))
  248. length += stringLength(len(sig.Blob))
  249. return length
  250. }
  251. func marshalSignature(to []byte, sig *signature) []byte {
  252. length := uint32(signatureLength(sig) - 4)
  253. to = marshalUint32(to, length)
  254. to = marshalString(to, []byte(sig.Format))
  255. to = marshalString(to, sig.Blob)
  256. return to
  257. }
  258. func parseSignatureBody(in []byte) (out *signature, rest []byte, ok bool) {
  259. var format []byte
  260. if format, in, ok = parseString(in); !ok {
  261. return
  262. }
  263. out = &signature{
  264. Format: string(format),
  265. }
  266. if out.Blob, in, ok = parseString(in); !ok {
  267. return
  268. }
  269. return out, in, ok
  270. }
  271. func parseSignature(in []byte) (out *signature, rest []byte, ok bool) {
  272. var sigBytes []byte
  273. if sigBytes, rest, ok = parseString(in); !ok {
  274. return
  275. }
  276. // TODO(hanwen): this is a bug; 'rest' gets swallowed.
  277. return parseSignatureBody(sigBytes)
  278. }