PageRenderTime 92ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/src/java/org/jruby/ext/openssl/impl/SignerInfoWithPkey.java

https://github.com/duncanmak/jruby-ossl
Java | 364 lines | 231 code | 48 blank | 85 comment | 36 complexity | a36b1b54d9a1576a54e03312608fe8b2 MD5 | raw file
  1. /***** BEGIN LICENSE BLOCK *****
  2. * Version: CPL 1.0/GPL 2.0/LGPL 2.1
  3. *
  4. * The contents of this file are subject to the Common Public
  5. * License Version 1.0 (the "License"); you may not use this file
  6. * except in compliance with the License. You may obtain a copy of
  7. * the License at http://www.eclipse.org/legal/cpl-v10.html
  8. *
  9. * Software distributed under the License is distributed on an "AS
  10. * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  11. * implied. See the License for the specific language governing
  12. * rights and limitations under the License.
  13. *
  14. * Copyright (C) 2008 Ola Bini <ola.bini@gmail.com>
  15. *
  16. * Alternatively, the contents of this file may be used under the terms of
  17. * either of the GNU General Public License Version 2 or later (the "GPL"),
  18. * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  19. * in which case the provisions of the GPL or the LGPL are applicable instead
  20. * of those above. If you wish to allow use of your version of this file only
  21. * under the terms of either the GPL or the LGPL, and not to allow others to
  22. * use your version of this file under the terms of the CPL, indicate your
  23. * decision by deleting the provisions above and replace them with the notice
  24. * and other provisions required by the GPL or the LGPL. If you do not delete
  25. * the provisions above, a recipient may use your version of this file under
  26. * the terms of any one of the CPL, the GPL or the LGPL.
  27. ***** END LICENSE BLOCK *****/
  28. package org.jruby.ext.openssl.impl;
  29. import java.io.ByteArrayInputStream;
  30. import java.io.IOException;
  31. import java.math.BigInteger;
  32. import java.security.MessageDigest;
  33. import java.security.PrivateKey;
  34. import java.security.interfaces.DSAPrivateKey;
  35. import java.security.interfaces.ECPrivateKey;
  36. import java.security.interfaces.RSAPrivateKey;
  37. import java.util.Enumeration;
  38. import org.bouncycastle.asn1.ASN1Encodable;
  39. import org.bouncycastle.asn1.ASN1EncodableVector;
  40. import org.bouncycastle.asn1.ASN1InputStream;
  41. import org.bouncycastle.asn1.ASN1OctetString;
  42. import org.bouncycastle.asn1.ASN1Sequence;
  43. import org.bouncycastle.asn1.ASN1Set;
  44. import org.bouncycastle.asn1.ASN1TaggedObject;
  45. import org.bouncycastle.asn1.DEREncodable;
  46. import org.bouncycastle.asn1.DERInteger;
  47. import org.bouncycastle.asn1.DERObject;
  48. import org.bouncycastle.asn1.DERObjectIdentifier;
  49. import org.bouncycastle.asn1.DERSequence;
  50. import org.bouncycastle.asn1.DERSet;
  51. import org.bouncycastle.asn1.DERTaggedObject;
  52. import org.bouncycastle.asn1.pkcs.Attribute;
  53. import org.bouncycastle.asn1.pkcs.IssuerAndSerialNumber;
  54. import org.bouncycastle.asn1.pkcs.SignerInfo;
  55. import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
  56. import org.bouncycastle.asn1.x509.X509Name;
  57. import org.jruby.ext.openssl.x509store.X509AuxCertificate;
  58. /**
  59. *
  60. * @author <a href="mailto:ola.bini@gmail.com">Ola Bini</a>
  61. */
  62. public class SignerInfoWithPkey extends ASN1Encodable {
  63. private DERInteger version;
  64. private IssuerAndSerialNumber issuerAndSerialNumber;
  65. private AlgorithmIdentifier digAlgorithm;
  66. private ASN1Set authenticatedAttributes;
  67. private AlgorithmIdentifier digEncryptionAlgorithm;
  68. private ASN1OctetString encryptedDigest;
  69. private ASN1Set unauthenticatedAttributes;
  70. public static SignerInfoWithPkey getInstance(Object o) {
  71. if(o instanceof SignerInfo) {
  72. return (SignerInfoWithPkey)o;
  73. } else if (o instanceof ASN1Sequence) {
  74. return new SignerInfoWithPkey((ASN1Sequence)o);
  75. }
  76. throw new IllegalArgumentException("unknown object in factory: " + o.getClass().getName());
  77. }
  78. public SignerInfoWithPkey dup() {
  79. SignerInfoWithPkey copy = new SignerInfoWithPkey(version,
  80. issuerAndSerialNumber,
  81. digAlgorithm,
  82. authenticatedAttributes,
  83. digEncryptionAlgorithm,
  84. encryptedDigest,
  85. unauthenticatedAttributes);
  86. copy.pkey = pkey;
  87. return copy;
  88. }
  89. SignerInfoWithPkey() {
  90. }
  91. public SignerInfoWithPkey(DERInteger version,
  92. IssuerAndSerialNumber issuerAndSerialNumber,
  93. AlgorithmIdentifier digAlgorithm,
  94. ASN1Set authenticatedAttributes,
  95. AlgorithmIdentifier digEncryptionAlgorithm,
  96. ASN1OctetString encryptedDigest,
  97. ASN1Set unauthenticatedAttributes) {
  98. this.version = version;
  99. this.issuerAndSerialNumber = issuerAndSerialNumber;
  100. this.digAlgorithm = digAlgorithm;
  101. this.authenticatedAttributes = authenticatedAttributes;
  102. this.digEncryptionAlgorithm = digEncryptionAlgorithm;
  103. this.encryptedDigest = encryptedDigest;
  104. this.unauthenticatedAttributes = unauthenticatedAttributes;
  105. }
  106. public SignerInfoWithPkey(ASN1Sequence seq) {
  107. Enumeration e = seq.getObjects();
  108. version = (DERInteger)e.nextElement();
  109. issuerAndSerialNumber = IssuerAndSerialNumber.getInstance(e.nextElement());
  110. digAlgorithm = AlgorithmIdentifier.getInstance(e.nextElement());
  111. Object obj = e.nextElement();
  112. if(obj instanceof ASN1TaggedObject) {
  113. authenticatedAttributes = ASN1Set.getInstance((ASN1TaggedObject)obj, false);
  114. digEncryptionAlgorithm = AlgorithmIdentifier.getInstance(e.nextElement());
  115. }
  116. else {
  117. authenticatedAttributes = null;
  118. digEncryptionAlgorithm = AlgorithmIdentifier.getInstance(obj);
  119. }
  120. encryptedDigest = ASN1OctetString.getInstance(e.nextElement());
  121. if(e.hasMoreElements()) {
  122. unauthenticatedAttributes = ASN1Set.getInstance((ASN1TaggedObject)e.nextElement(), false);
  123. }
  124. else {
  125. unauthenticatedAttributes = null;
  126. }
  127. }
  128. public DERInteger getVersion() {
  129. return version;
  130. }
  131. public IssuerAndSerialNumber getIssuerAndSerialNumber() {
  132. return issuerAndSerialNumber;
  133. }
  134. public ASN1Set getAuthenticatedAttributes() {
  135. return authenticatedAttributes;
  136. }
  137. public AlgorithmIdentifier getDigestAlgorithm() {
  138. return digAlgorithm;
  139. }
  140. public ASN1OctetString getEncryptedDigest() {
  141. return encryptedDigest;
  142. }
  143. public AlgorithmIdentifier getDigestEncryptionAlgorithm() {
  144. return digEncryptionAlgorithm;
  145. }
  146. public ASN1Set getUnauthenticatedAttributes() {
  147. return unauthenticatedAttributes;
  148. }
  149. /* c: PKCS7_SIGNER_INFO_set
  150. *
  151. */
  152. public void set(X509AuxCertificate x509, PrivateKey pkey, MessageDigest dgst) throws PKCS7Exception {
  153. boolean dsa =
  154. (pkey instanceof DSAPrivateKey) ||
  155. (pkey instanceof ECPrivateKey);
  156. version = new DERInteger(1);
  157. try {
  158. X509Name issuer = X509Name.getInstance(new ASN1InputStream(new ByteArrayInputStream(x509.getIssuerX500Principal().getEncoded())).readObject());
  159. BigInteger serial = x509.getSerialNumber();
  160. issuerAndSerialNumber = new IssuerAndSerialNumber(issuer, serial);
  161. } catch(IOException e) {
  162. throw new PKCS7Exception(-1, -1, e);
  163. }
  164. this.pkey = pkey;
  165. if(dsa) {
  166. digAlgorithm = new AlgorithmIdentifier(ASN1Registry.nid2obj(ASN1Registry.NID_sha1));
  167. } else {
  168. digAlgorithm = new AlgorithmIdentifier(ASN1Registry.nid2obj(EVP.type(dgst)));
  169. }
  170. if(pkey instanceof RSAPrivateKey) {
  171. digEncryptionAlgorithm = new AlgorithmIdentifier(ASN1Registry.nid2obj(ASN1Registry.NID_rsaEncryption));
  172. } else if(pkey instanceof DSAPrivateKey) {
  173. digEncryptionAlgorithm = new AlgorithmIdentifier(ASN1Registry.nid2obj(ASN1Registry.NID_dsa));
  174. } else if(pkey instanceof ECPrivateKey) {
  175. digEncryptionAlgorithm = new AlgorithmIdentifier(ASN1Registry.nid2obj(ASN1Registry.NID_ecdsa_with_SHA1));
  176. }
  177. }
  178. /**
  179. * Produce an object suitable for an ASN1OutputStream.
  180. * <pre>
  181. * SignerInfo ::= SEQUENCE {
  182. * version Version,
  183. * issuerAndSerialNumber IssuerAndSerialNumber,
  184. * digestAlgorithm DigestAlgorithmIdentifier,
  185. * authenticatedAttributes [0] IMPLICIT Attributes OPTIONAL,
  186. * digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier,
  187. * encryptedDigest EncryptedDigest,
  188. * unauthenticatedAttributes [1] IMPLICIT Attributes OPTIONAL
  189. * }
  190. *
  191. * EncryptedDigest ::= OCTET STRING
  192. *
  193. * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
  194. *
  195. * DigestEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
  196. * </pre>
  197. */
  198. public DERObject toASN1Object() {
  199. ASN1EncodableVector v = new ASN1EncodableVector();
  200. v.add(version);
  201. v.add(issuerAndSerialNumber);
  202. v.add(digAlgorithm);
  203. if (authenticatedAttributes != null) {
  204. v.add(new DERTaggedObject(false, 0, authenticatedAttributes));
  205. }
  206. v.add(digEncryptionAlgorithm);
  207. v.add(encryptedDigest);
  208. if (unauthenticatedAttributes != null) {
  209. v.add(new DERTaggedObject(false, 1, unauthenticatedAttributes));
  210. }
  211. return new DERSequence(v);
  212. }
  213. /**
  214. * Describe pkey here.
  215. */
  216. private PrivateKey pkey;
  217. /**
  218. * Get the <code>Pkey</code> value.
  219. *
  220. * @return a <code>PrivateKey</code> value
  221. */
  222. public final PrivateKey getPkey() {
  223. return pkey;
  224. }
  225. /**
  226. * Set the <code>Pkey</code> value.
  227. *
  228. * @param newPkey The new Pkey value.
  229. */
  230. public final void setPkey(final PrivateKey newPkey) {
  231. this.pkey = newPkey;
  232. }
  233. public void setAuthenticatedAttributes(ASN1Set authAttr) {
  234. this.authenticatedAttributes = authAttr;
  235. }
  236. public void setUnauthenticatedAttributes(ASN1Set unauthAttr) {
  237. this.unauthenticatedAttributes = unauthAttr;
  238. }
  239. public void setEncryptedDigest(ASN1OctetString encryptedDigest) {
  240. this.encryptedDigest = encryptedDigest;
  241. }
  242. /** c: PKCS7_get_signed_attribute
  243. *
  244. */
  245. public DEREncodable getSignedAttribute(int nid) {
  246. return getAttribute(this.authenticatedAttributes, nid);
  247. }
  248. /** c: PKCS7_get_attribute
  249. *
  250. */
  251. public DEREncodable getAttribute(int nid) {
  252. return getAttribute(this.unauthenticatedAttributes, nid);
  253. }
  254. /** c: static get_attribute
  255. *
  256. */
  257. public static DEREncodable getAttribute(ASN1Set sk, int nid) {
  258. Attribute xa = null;
  259. DERObjectIdentifier o = ASN1Registry.nid2obj(nid);
  260. if(null == o || null == sk) {
  261. return null;
  262. }
  263. for(Enumeration e = sk.getObjects(); e.hasMoreElements();) {
  264. Object val = e.nextElement();
  265. if(val instanceof Attribute) {
  266. xa = (Attribute)val;
  267. } else {
  268. xa = Attribute.getInstance(val);
  269. }
  270. if(o.equals(xa.getAttrType())) {
  271. if(xa.getAttrValues().size() > 0) {
  272. return xa.getAttrValues().getObjectAt(0);
  273. } else {
  274. return null;
  275. }
  276. }
  277. }
  278. return null;
  279. }
  280. /** c: PKCS7_add_signed_attribute
  281. *
  282. */
  283. public void addSignedAttribute(int atrType, DEREncodable value) {
  284. this.authenticatedAttributes = addAttribute(this.authenticatedAttributes, atrType, value);
  285. }
  286. /** c: PKCS7_add_attribute
  287. *
  288. */
  289. public void addAttribute(int atrType, DEREncodable value) {
  290. this.unauthenticatedAttributes = addAttribute(this.unauthenticatedAttributes, atrType, value);
  291. }
  292. /** c: static add_attribute
  293. *
  294. */
  295. private ASN1Set addAttribute(ASN1Set base, int atrType, DEREncodable value) {
  296. ASN1EncodableVector vector = new ASN1EncodableVector();
  297. if(base == null) {
  298. base = new DERSet();
  299. }
  300. Attribute attr = null;
  301. for(Enumeration e = base.getObjects(); e.hasMoreElements();) {
  302. Object val = e.nextElement();
  303. if(val instanceof Attribute) {
  304. attr = (Attribute)val;
  305. } else {
  306. attr = Attribute.getInstance(val);
  307. }
  308. if(ASN1Registry.obj2nid(attr.getAttrType()) != atrType) {
  309. vector.add(attr);
  310. }
  311. }
  312. attr = new Attribute(ASN1Registry.nid2obj(atrType), new DERSet(value));
  313. vector.add(attr);
  314. return new DERSet(vector);
  315. }
  316. }// SignerInfoWithPkey