certs.go 7.4 KB

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