您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

PkiTestUtils.java 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. /* ====================================================================
  2. Licensed to the Apache Software Foundation (ASF) under one or more
  3. contributor license agreements. See the NOTICE file distributed with
  4. this work for additional information regarding copyright ownership.
  5. The ASF licenses this file to You under the Apache License, Version 2.0
  6. (the "License"); you may not use this file except in compliance with
  7. the License. You may obtain a copy of the License at
  8. http://www.apache.org/licenses/LICENSE-2.0
  9. Unless required by applicable law or agreed to in writing, software
  10. distributed under the License is distributed on an "AS IS" BASIS,
  11. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. See the License for the specific language governing permissions and
  13. limitations under the License.
  14. ==================================================================== */
  15. package org.apache.poi.poifs.crypt;
  16. import java.io.IOException;
  17. import java.io.InputStream;
  18. import java.io.StringWriter;
  19. import java.math.BigInteger;
  20. import java.security.KeyPair;
  21. import java.security.KeyPairGenerator;
  22. import java.security.PrivateKey;
  23. import java.security.PublicKey;
  24. import java.security.SecureRandom;
  25. import java.security.cert.CRLException;
  26. import java.security.cert.CertificateEncodingException;
  27. import java.security.cert.CertificateException;
  28. import java.security.cert.X509CRL;
  29. import java.security.cert.X509Certificate;
  30. import java.security.interfaces.RSAPublicKey;
  31. import java.security.spec.RSAKeyGenParameterSpec;
  32. import java.util.Date;
  33. import javax.xml.parsers.DocumentBuilder;
  34. import javax.xml.parsers.DocumentBuilderFactory;
  35. import javax.xml.parsers.ParserConfigurationException;
  36. import javax.xml.transform.OutputKeys;
  37. import javax.xml.transform.Result;
  38. import javax.xml.transform.Source;
  39. import javax.xml.transform.Transformer;
  40. import javax.xml.transform.TransformerException;
  41. import javax.xml.transform.TransformerFactory;
  42. import javax.xml.transform.dom.DOMSource;
  43. import javax.xml.transform.stream.StreamResult;
  44. import org.bouncycastle.asn1.DERIA5String;
  45. import org.bouncycastle.asn1.DEROctetString;
  46. import org.bouncycastle.asn1.DERSequence;
  47. import org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers;
  48. import org.bouncycastle.asn1.x500.X500Name;
  49. import org.bouncycastle.asn1.x509.AuthorityInformationAccess;
  50. import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier;
  51. import org.bouncycastle.asn1.x509.BasicConstraints;
  52. import org.bouncycastle.asn1.x509.CRLNumber;
  53. import org.bouncycastle.asn1.x509.CRLReason;
  54. import org.bouncycastle.asn1.x509.DistributionPoint;
  55. import org.bouncycastle.asn1.x509.DistributionPointName;
  56. import org.bouncycastle.asn1.x509.Extension;
  57. import org.bouncycastle.asn1.x509.Extensions;
  58. import org.bouncycastle.asn1.x509.GeneralName;
  59. import org.bouncycastle.asn1.x509.GeneralNames;
  60. import org.bouncycastle.asn1.x509.KeyUsage;
  61. import org.bouncycastle.asn1.x509.SubjectKeyIdentifier;
  62. import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
  63. import org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
  64. import org.bouncycastle.cert.X509CRLHolder;
  65. import org.bouncycastle.cert.X509CertificateHolder;
  66. import org.bouncycastle.cert.X509ExtensionUtils;
  67. import org.bouncycastle.cert.X509v2CRLBuilder;
  68. import org.bouncycastle.cert.X509v3CertificateBuilder;
  69. import org.bouncycastle.cert.jcajce.JcaX509CRLConverter;
  70. import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
  71. import org.bouncycastle.cert.ocsp.BasicOCSPResp;
  72. import org.bouncycastle.cert.ocsp.BasicOCSPRespBuilder;
  73. import org.bouncycastle.cert.ocsp.CertificateID;
  74. import org.bouncycastle.cert.ocsp.CertificateStatus;
  75. import org.bouncycastle.cert.ocsp.OCSPReq;
  76. import org.bouncycastle.cert.ocsp.OCSPReqBuilder;
  77. import org.bouncycastle.cert.ocsp.OCSPResp;
  78. import org.bouncycastle.cert.ocsp.OCSPRespBuilder;
  79. import org.bouncycastle.cert.ocsp.Req;
  80. import org.bouncycastle.cert.ocsp.RevokedStatus;
  81. import org.bouncycastle.crypto.params.RSAKeyParameters;
  82. import org.bouncycastle.crypto.util.SubjectPublicKeyInfoFactory;
  83. import org.bouncycastle.operator.ContentSigner;
  84. import org.bouncycastle.operator.DigestCalculator;
  85. import org.bouncycastle.operator.OperatorCreationException;
  86. import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
  87. import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
  88. import org.w3c.dom.Document;
  89. import org.w3c.dom.Node;
  90. import org.xml.sax.InputSource;
  91. import org.xml.sax.SAXException;
  92. public class PkiTestUtils {
  93. private PkiTestUtils() {
  94. super();
  95. }
  96. static KeyPair generateKeyPair() throws Exception {
  97. KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
  98. SecureRandom random = new SecureRandom();
  99. keyPairGenerator.initialize(new RSAKeyGenParameterSpec(1024,
  100. RSAKeyGenParameterSpec.F4), random);
  101. KeyPair keyPair = keyPairGenerator.generateKeyPair();
  102. return keyPair;
  103. }
  104. static X509Certificate generateCertificate(PublicKey subjectPublicKey,
  105. String subjectDn, Date notBefore, Date notAfter,
  106. X509Certificate issuerCertificate, PrivateKey issuerPrivateKey,
  107. boolean caFlag, int pathLength, String crlUri, String ocspUri,
  108. KeyUsage keyUsage)
  109. throws IOException, OperatorCreationException, CertificateException
  110. {
  111. String signatureAlgorithm = "SHA1withRSA";
  112. X500Name issuerName;
  113. if (issuerCertificate != null) {
  114. issuerName = new X509CertificateHolder(issuerCertificate.getEncoded()).getIssuer();
  115. } else {
  116. issuerName = new X500Name(subjectDn);
  117. }
  118. RSAPublicKey rsaPubKey = (RSAPublicKey)subjectPublicKey;
  119. RSAKeyParameters rsaSpec = new RSAKeyParameters(false, rsaPubKey.getModulus(), rsaPubKey.getPublicExponent());
  120. SubjectPublicKeyInfo subjectPublicKeyInfo =
  121. SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(rsaSpec);
  122. DigestCalculator digestCalc = new JcaDigestCalculatorProviderBuilder()
  123. .setProvider("BC").build().get(CertificateID.HASH_SHA1);
  124. X509v3CertificateBuilder certificateGenerator = new X509v3CertificateBuilder(
  125. issuerName
  126. , new BigInteger(128, new SecureRandom())
  127. , notBefore
  128. , notAfter
  129. , new X500Name(subjectDn)
  130. , subjectPublicKeyInfo
  131. );
  132. X509ExtensionUtils exUtils = new X509ExtensionUtils(digestCalc);
  133. SubjectKeyIdentifier subKeyId = exUtils.createSubjectKeyIdentifier(subjectPublicKeyInfo);
  134. AuthorityKeyIdentifier autKeyId = (issuerCertificate != null)
  135. ? exUtils.createAuthorityKeyIdentifier(new X509CertificateHolder(issuerCertificate.getEncoded()))
  136. : exUtils.createAuthorityKeyIdentifier(subjectPublicKeyInfo);
  137. certificateGenerator.addExtension(Extension.subjectKeyIdentifier, false, subKeyId);
  138. certificateGenerator.addExtension(Extension.authorityKeyIdentifier, false, autKeyId);
  139. if (caFlag) {
  140. BasicConstraints bc;
  141. if (-1 == pathLength) {
  142. bc = new BasicConstraints(true);
  143. } else {
  144. bc = new BasicConstraints(pathLength);
  145. }
  146. certificateGenerator.addExtension(Extension.basicConstraints, false, bc);
  147. }
  148. if (null != crlUri) {
  149. int uri = GeneralName.uniformResourceIdentifier;
  150. DERIA5String crlUriDer = new DERIA5String(crlUri);
  151. GeneralName gn = new GeneralName(uri, crlUriDer);
  152. DERSequence gnDer = new DERSequence(gn);
  153. GeneralNames gns = GeneralNames.getInstance(gnDer);
  154. DistributionPointName dpn = new DistributionPointName(0, gns);
  155. DistributionPoint distp = new DistributionPoint(dpn, null, null);
  156. DERSequence distpDer = new DERSequence(distp);
  157. certificateGenerator.addExtension(Extension.cRLDistributionPoints, false, distpDer);
  158. }
  159. if (null != ocspUri) {
  160. int uri = GeneralName.uniformResourceIdentifier;
  161. GeneralName ocspName = new GeneralName(uri, ocspUri);
  162. AuthorityInformationAccess authorityInformationAccess =
  163. new AuthorityInformationAccess(X509ObjectIdentifiers.ocspAccessMethod, ocspName);
  164. certificateGenerator.addExtension(Extension.authorityInfoAccess, false, authorityInformationAccess);
  165. }
  166. if (null != keyUsage) {
  167. certificateGenerator.addExtension(Extension.keyUsage, true, keyUsage);
  168. }
  169. JcaContentSignerBuilder signerBuilder = new JcaContentSignerBuilder(signatureAlgorithm);
  170. signerBuilder.setProvider("BC");
  171. X509CertificateHolder certHolder =
  172. certificateGenerator.build(signerBuilder.build(issuerPrivateKey));
  173. /*
  174. * Next certificate factory trick is needed to make sure that the
  175. * certificate delivered to the caller is provided by the default
  176. * security provider instead of BouncyCastle. If we don't do this trick
  177. * we might run into trouble when trying to use the CertPath validator.
  178. */
  179. // CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
  180. // certificate = (X509Certificate) certificateFactory
  181. // .generateCertificate(new ByteArrayInputStream(certificate
  182. // .getEncoded()));
  183. return new JcaX509CertificateConverter().getCertificate(certHolder);
  184. }
  185. static Document loadDocument(InputStream documentInputStream)
  186. throws ParserConfigurationException, SAXException, IOException {
  187. InputSource inputSource = new InputSource(documentInputStream);
  188. DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory
  189. .newInstance();
  190. documentBuilderFactory.setNamespaceAware(true);
  191. DocumentBuilder documentBuilder = documentBuilderFactory
  192. .newDocumentBuilder();
  193. Document document = documentBuilder.parse(inputSource);
  194. return document;
  195. }
  196. static String toString(Node dom) throws TransformerException {
  197. Source source = new DOMSource(dom);
  198. StringWriter stringWriter = new StringWriter();
  199. Result result = new StreamResult(stringWriter);
  200. TransformerFactory transformerFactory = TransformerFactory
  201. .newInstance();
  202. Transformer transformer = transformerFactory.newTransformer();
  203. /*
  204. * We have to omit the ?xml declaration if we want to embed the
  205. * document.
  206. */
  207. transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
  208. transformer.transform(source, result);
  209. return stringWriter.getBuffer().toString();
  210. }
  211. public static X509CRL generateCrl(X509Certificate issuer, PrivateKey issuerPrivateKey)
  212. throws CertificateEncodingException, IOException, CRLException, OperatorCreationException {
  213. X509CertificateHolder holder = new X509CertificateHolder(issuer.getEncoded());
  214. X509v2CRLBuilder crlBuilder = new X509v2CRLBuilder(holder.getIssuer(), new Date());
  215. crlBuilder.setNextUpdate(new Date(new Date().getTime() + 100000));
  216. JcaContentSignerBuilder contentBuilder = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC");
  217. CRLNumber crlNumber = new CRLNumber(new BigInteger("1234"));
  218. crlBuilder.addExtension(Extension.cRLNumber, false, crlNumber);
  219. X509CRLHolder x509Crl = crlBuilder.build(contentBuilder.build(issuerPrivateKey));
  220. return new JcaX509CRLConverter().setProvider("BC").getCRL(x509Crl);
  221. }
  222. public static OCSPResp createOcspResp(X509Certificate certificate,
  223. boolean revoked, X509Certificate issuerCertificate,
  224. X509Certificate ocspResponderCertificate,
  225. PrivateKey ocspResponderPrivateKey, String signatureAlgorithm,
  226. long nonceTimeinMillis)
  227. throws Exception {
  228. DigestCalculator digestCalc = new JcaDigestCalculatorProviderBuilder()
  229. .setProvider("BC").build().get(CertificateID.HASH_SHA1);
  230. X509CertificateHolder issuerHolder = new X509CertificateHolder(issuerCertificate.getEncoded());
  231. CertificateID certId = new CertificateID(digestCalc, issuerHolder, certificate.getSerialNumber());
  232. // request
  233. //create a nonce to avoid replay attack
  234. BigInteger nonce = BigInteger.valueOf(nonceTimeinMillis);
  235. DEROctetString nonceDer = new DEROctetString(nonce.toByteArray());
  236. Extension ext = new Extension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce, true, nonceDer);
  237. Extensions exts = new Extensions(ext);
  238. OCSPReqBuilder ocspReqBuilder = new OCSPReqBuilder();
  239. ocspReqBuilder.addRequest(certId);
  240. ocspReqBuilder.setRequestExtensions(exts);
  241. OCSPReq ocspReq = ocspReqBuilder.build();
  242. SubjectPublicKeyInfo keyInfo = new SubjectPublicKeyInfo
  243. (CertificateID.HASH_SHA1, ocspResponderCertificate.getPublicKey().getEncoded());
  244. BasicOCSPRespBuilder basicOCSPRespBuilder = new BasicOCSPRespBuilder(keyInfo, digestCalc);
  245. basicOCSPRespBuilder.setResponseExtensions(exts);
  246. // request processing
  247. Req[] requestList = ocspReq.getRequestList();
  248. for (Req ocspRequest : requestList) {
  249. CertificateID certificateID = ocspRequest.getCertID();
  250. CertificateStatus certificateStatus = CertificateStatus.GOOD;
  251. if (revoked) {
  252. certificateStatus = new RevokedStatus(new Date(), CRLReason.privilegeWithdrawn);
  253. }
  254. basicOCSPRespBuilder.addResponse(certificateID, certificateStatus);
  255. }
  256. // basic response generation
  257. X509CertificateHolder[] chain = null;
  258. if (!ocspResponderCertificate.equals(issuerCertificate)) {
  259. // TODO: HorribleProxy can't convert array input params yet
  260. chain = new X509CertificateHolder[] {
  261. new X509CertificateHolder(ocspResponderCertificate.getEncoded()),
  262. issuerHolder
  263. };
  264. }
  265. ContentSigner contentSigner = new JcaContentSignerBuilder("SHA1withRSA")
  266. .setProvider("BC").build(ocspResponderPrivateKey);
  267. BasicOCSPResp basicOCSPResp = basicOCSPRespBuilder.build(contentSigner, chain, new Date(nonceTimeinMillis));
  268. OCSPRespBuilder ocspRespBuilder = new OCSPRespBuilder();
  269. OCSPResp ocspResp = ocspRespBuilder.build(OCSPRespBuilder.SUCCESSFUL, basicOCSPResp);
  270. return ocspResp;
  271. }
  272. }