You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

PushCertificate.java 6.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. /*
  2. * Copyright (C) 2015, Google Inc.
  3. * and other copyright owners as documented in the project's IP log.
  4. *
  5. * This program and the accompanying materials are made available
  6. * under the terms of the Eclipse Distribution License v1.0 which
  7. * accompanies this distribution, is reproduced below, and is
  8. * available at http://www.eclipse.org/org/documents/edl-v10.php
  9. *
  10. * All rights reserved.
  11. *
  12. * Redistribution and use in source and binary forms, with or
  13. * without modification, are permitted provided that the following
  14. * conditions are met:
  15. *
  16. * - Redistributions of source code must retain the above copyright
  17. * notice, this list of conditions and the following disclaimer.
  18. *
  19. * - Redistributions in binary form must reproduce the above
  20. * copyright notice, this list of conditions and the following
  21. * disclaimer in the documentation and/or other materials provided
  22. * with the distribution.
  23. *
  24. * - Neither the name of the Eclipse Foundation, Inc. nor the
  25. * names of its contributors may be used to endorse or promote
  26. * products derived from this software without specific prior
  27. * written permission.
  28. *
  29. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  30. * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  31. * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  32. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  33. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  34. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  35. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  36. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  37. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  38. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  40. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  41. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  42. */
  43. package org.eclipse.jgit.transport;
  44. import static org.eclipse.jgit.transport.PushCertificateParser.NONCE;
  45. import static org.eclipse.jgit.transport.PushCertificateParser.PUSHEE;
  46. import static org.eclipse.jgit.transport.PushCertificateParser.PUSHER;
  47. import static org.eclipse.jgit.transport.PushCertificateParser.VERSION;
  48. import java.text.MessageFormat;
  49. import java.util.List;
  50. import org.eclipse.jgit.internal.JGitText;
  51. /**
  52. * The required information to verify the push.
  53. * <p>
  54. * A valid certificate will not return null from any getter methods; callers may
  55. * assume that any null value indicates a missing or invalid certificate.
  56. *
  57. * @since 4.0
  58. */
  59. public class PushCertificate {
  60. /** Verification result of the nonce returned during push. */
  61. public enum NonceStatus {
  62. /** Nonce was not expected, yet client sent one anyway. */
  63. UNSOLICITED,
  64. /** Nonce is invalid and did not match server's expectations. */
  65. BAD,
  66. /** Nonce is required, but was not sent by client. */
  67. MISSING,
  68. /**
  69. * Received nonce matches sent nonce, or is valid within the accepted slop
  70. * window.
  71. */
  72. OK,
  73. /** Received nonce is valid, but outside the accepted slop window. */
  74. SLOP
  75. }
  76. private final String version;
  77. private final PushCertificateIdent pusher;
  78. private final String pushee;
  79. private final String nonce;
  80. private final NonceStatus nonceStatus;
  81. private final List<ReceiveCommand> commands;
  82. private final String signature;
  83. PushCertificate(String version, PushCertificateIdent pusher, String pushee,
  84. String nonce, NonceStatus nonceStatus, List<ReceiveCommand> commands,
  85. String signature) {
  86. if (version == null || version.isEmpty()) {
  87. throw new IllegalArgumentException(MessageFormat.format(
  88. JGitText.get().pushCertificateInvalidField, VERSION));
  89. }
  90. if (pusher == null) {
  91. throw new IllegalArgumentException(MessageFormat.format(
  92. JGitText.get().pushCertificateInvalidField, PUSHER));
  93. }
  94. if (nonce == null || nonce.isEmpty()) {
  95. throw new IllegalArgumentException(MessageFormat.format(
  96. JGitText.get().pushCertificateInvalidField, NONCE));
  97. }
  98. if (nonceStatus == null) {
  99. throw new IllegalArgumentException(MessageFormat.format(
  100. JGitText.get().pushCertificateInvalidField,
  101. "nonce status")); //$NON-NLS-1$
  102. }
  103. if (commands == null || commands.isEmpty()) {
  104. throw new IllegalArgumentException(MessageFormat.format(
  105. JGitText.get().pushCertificateInvalidField,
  106. "command")); //$NON-NLS-1$
  107. }
  108. if (signature == null || signature.isEmpty()) {
  109. throw new IllegalArgumentException(
  110. JGitText.get().pushCertificateInvalidSignature);
  111. }
  112. if (!signature.startsWith(PushCertificateParser.BEGIN_SIGNATURE)
  113. || !signature.endsWith(PushCertificateParser.END_SIGNATURE + '\n')) {
  114. throw new IllegalArgumentException(
  115. JGitText.get().pushCertificateInvalidSignature);
  116. }
  117. this.version = version;
  118. this.pusher = pusher;
  119. this.pushee = pushee;
  120. this.nonce = nonce;
  121. this.nonceStatus = nonceStatus;
  122. this.commands = commands;
  123. this.signature = signature;
  124. }
  125. /**
  126. * @return the certificate version string.
  127. * @since 4.1
  128. */
  129. public String getVersion() {
  130. return version;
  131. }
  132. /**
  133. * @return the raw line that signed the cert, as a string.
  134. * @since 4.0
  135. */
  136. public String getPusher() {
  137. return pusher.getRaw();
  138. }
  139. /**
  140. * @return identity of the pusher who signed the cert.
  141. * @since 4.1
  142. */
  143. public PushCertificateIdent getPusherIdent() {
  144. return pusher;
  145. }
  146. /**
  147. * @return URL of the repository the push was originally sent to.
  148. * @since 4.0
  149. */
  150. public String getPushee() {
  151. return pushee;
  152. }
  153. /**
  154. * @return the raw nonce value that was presented by the pusher.
  155. * @since 4.1
  156. */
  157. public String getNonce() {
  158. return nonce;
  159. }
  160. /**
  161. * @return verification status of the nonce embedded in the certificate.
  162. * @since 4.0
  163. */
  164. public NonceStatus getNonceStatus() {
  165. return nonceStatus;
  166. }
  167. /**
  168. * @return the list of commands as one string to be feed into the signature
  169. * verifier.
  170. * @since 4.1
  171. */
  172. public List<ReceiveCommand> getCommands() {
  173. return commands;
  174. }
  175. /**
  176. * @return the raw signature, consisting of the lines received between the
  177. * lines {@code "----BEGIN GPG SIGNATURE-----\n"} and
  178. * {@code "----END GPG SIGNATURE-----\n}", inclusive.
  179. * @since 4.0
  180. */
  181. public String getSignature() {
  182. return signature;
  183. }
  184. /**
  185. * @return text payload of the certificate for the signature verifier.
  186. * @since 4.1
  187. */
  188. public String toText() {
  189. StringBuilder sb = new StringBuilder()
  190. .append(VERSION).append(' ').append(version).append('\n')
  191. .append(PUSHER).append(' ').append(getPusher())
  192. .append('\n')
  193. .append(PUSHEE).append(' ').append(pushee).append('\n')
  194. .append(NONCE).append(' ').append(nonce).append('\n')
  195. .append('\n');
  196. for (ReceiveCommand cmd : commands) {
  197. sb.append(cmd.getOldId().name())
  198. .append(' ').append(cmd.getNewId().name())
  199. .append(' ').append(cmd.getRefName()).append('\n');
  200. }
  201. return sb.toString();
  202. }
  203. }