/security/nss/cmd/lib/pppolicy.c

http://github.com/zpao/v8monkey · C · 299 lines · 205 code · 36 blank · 58 comment · 47 complexity · 7801cfb83fb4a9dac1aab45ea717b7d3 MD5 · raw file

  1. /* ***** BEGIN LICENSE BLOCK *****
  2. * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  3. *
  4. * The contents of this file are subject to the Mozilla Public License Version
  5. * 1.1 (the "License"); you may not use this file except in compliance with
  6. * the License. You may obtain a copy of the License at
  7. * http://www.mozilla.org/MPL/
  8. *
  9. * Software distributed under the License is distributed on an "AS IS" basis,
  10. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11. * for the specific language governing rights and limitations under the
  12. * License.
  13. *
  14. * The Original Code is the Netscape security libraries.
  15. *
  16. * The Initial Developer of the Original Code is
  17. * Netscape Communications Corporation.
  18. * Portions created by the Initial Developer are Copyright (C) 2004
  19. * the Initial Developer. All Rights Reserved.
  20. *
  21. * Contributor(s):
  22. *
  23. * Alternatively, the contents of this file may be used under the terms of
  24. * either the GNU General Public License Version 2 or later (the "GPL"), or
  25. * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  26. * in which case the provisions of the GPL or the LGPL are applicable instead
  27. * of those above. If you wish to allow use of your version of this file only
  28. * under the terms of either the GPL or the LGPL, and not to allow others to
  29. * use your version of this file under the terms of the MPL, indicate your
  30. * decision by deleting the provisions above and replace them with the notice
  31. * and other provisions required by the GPL or the LGPL. If you do not delete
  32. * the provisions above, a recipient may use your version of this file under
  33. * the terms of any one of the MPL, the GPL or the LGPL.
  34. *
  35. * ***** END LICENSE BLOCK ***** */
  36. /*
  37. * Support for various policy related extensions
  38. *
  39. * $Id: pppolicy.c,v 1.5 2011/11/16 19:12:30 kaie%kuix.de Exp $
  40. */
  41. #include "seccomon.h"
  42. #include "secport.h"
  43. #include "secder.h"
  44. #include "cert.h"
  45. #include "secoid.h"
  46. #include "secasn1.h"
  47. #include "secerr.h"
  48. #include "nspr.h"
  49. #include "secutil.h"
  50. /* This implementation is derived from the one in nss/lib/certdb/policyxtn.c .
  51. ** The chief difference is the addition of the OPTIONAL flag to many
  52. ** parts. The idea is to be able to parse and print as much of the
  53. ** policy extension as possible, even if some parts are invalid.
  54. **
  55. ** If this approach still is unable to decode policy extensions that
  56. ** contain invalid parts, then the next approach will be to parse
  57. ** the PolicyInfos as a SEQUENCE of ANYs, and then parse each of them
  58. ** as PolicyInfos, with the PolicyQualifiers being ANYs, and finally
  59. ** parse each of the PolicyQualifiers.
  60. */
  61. static const SEC_ASN1Template secu_PolicyQualifierTemplate[] = {
  62. { SEC_ASN1_SEQUENCE,
  63. 0, NULL, sizeof(CERTPolicyQualifier) },
  64. { SEC_ASN1_OBJECT_ID,
  65. offsetof(CERTPolicyQualifier, qualifierID) },
  66. { SEC_ASN1_ANY | SEC_ASN1_OPTIONAL,
  67. offsetof(CERTPolicyQualifier, qualifierValue) },
  68. { 0 }
  69. };
  70. static const SEC_ASN1Template secu_PolicyInfoTemplate[] = {
  71. { SEC_ASN1_SEQUENCE,
  72. 0, NULL, sizeof(CERTPolicyInfo) },
  73. { SEC_ASN1_OBJECT_ID,
  74. offsetof(CERTPolicyInfo, policyID) },
  75. { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_OPTIONAL,
  76. offsetof(CERTPolicyInfo, policyQualifiers),
  77. secu_PolicyQualifierTemplate },
  78. { 0 }
  79. };
  80. static const SEC_ASN1Template secu_CertificatePoliciesTemplate[] = {
  81. { SEC_ASN1_SEQUENCE_OF,
  82. offsetof(CERTCertificatePolicies, policyInfos),
  83. secu_PolicyInfoTemplate, sizeof(CERTCertificatePolicies) }
  84. };
  85. static CERTCertificatePolicies *
  86. secu_DecodeCertificatePoliciesExtension(SECItem *extnValue)
  87. {
  88. PRArenaPool *arena = NULL;
  89. SECStatus rv;
  90. CERTCertificatePolicies *policies;
  91. CERTPolicyInfo **policyInfos, *policyInfo;
  92. CERTPolicyQualifier **policyQualifiers, *policyQualifier;
  93. SECItem newExtnValue;
  94. /* make a new arena */
  95. arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
  96. if ( !arena ) {
  97. goto loser;
  98. }
  99. /* allocate the certifiate policies structure */
  100. policies = PORT_ArenaZNew(arena, CERTCertificatePolicies);
  101. if ( policies == NULL ) {
  102. goto loser;
  103. }
  104. policies->arena = arena;
  105. /* copy the DER into the arena, since Quick DER returns data that points
  106. into the DER input, which may get freed by the caller */
  107. rv = SECITEM_CopyItem(arena, &newExtnValue, extnValue);
  108. if ( rv != SECSuccess ) {
  109. goto loser;
  110. }
  111. /* decode the policy info */
  112. rv = SEC_QuickDERDecodeItem(arena, policies,
  113. secu_CertificatePoliciesTemplate,
  114. &newExtnValue);
  115. if ( rv != SECSuccess ) {
  116. goto loser;
  117. }
  118. /* initialize the oid tags */
  119. policyInfos = policies->policyInfos;
  120. while (policyInfos != NULL && *policyInfos != NULL ) {
  121. policyInfo = *policyInfos;
  122. policyInfo->oid = SECOID_FindOIDTag(&policyInfo->policyID);
  123. policyQualifiers = policyInfo->policyQualifiers;
  124. while ( policyQualifiers && *policyQualifiers != NULL ) {
  125. policyQualifier = *policyQualifiers;
  126. policyQualifier->oid =
  127. SECOID_FindOIDTag(&policyQualifier->qualifierID);
  128. policyQualifiers++;
  129. }
  130. policyInfos++;
  131. }
  132. return(policies);
  133. loser:
  134. if ( arena != NULL ) {
  135. PORT_FreeArena(arena, PR_FALSE);
  136. }
  137. return(NULL);
  138. }
  139. static char *
  140. itemToString(SECItem *item)
  141. {
  142. char *string;
  143. string = PORT_ZAlloc(item->len+1);
  144. if (string == NULL) return NULL;
  145. PORT_Memcpy(string,item->data,item->len);
  146. string[item->len] = 0;
  147. return string;
  148. }
  149. static SECStatus
  150. secu_PrintUserNoticeQualifier(FILE *out, SECItem * qualifierValue,
  151. char *msg, int level)
  152. {
  153. CERTUserNotice *userNotice = NULL;
  154. if (qualifierValue)
  155. userNotice = CERT_DecodeUserNotice(qualifierValue);
  156. if (userNotice) {
  157. if (userNotice->noticeReference.organization.len != 0) {
  158. char *string =
  159. itemToString(&userNotice->noticeReference.organization);
  160. SECItem **itemList = userNotice->noticeReference.noticeNumbers;
  161. while (itemList && *itemList) {
  162. SECU_PrintInteger(out,*itemList,string,level+1);
  163. itemList++;
  164. }
  165. PORT_Free(string);
  166. }
  167. if (userNotice->displayText.len != 0) {
  168. SECU_PrintString(out,&userNotice->displayText,
  169. "Display Text", level+1);
  170. }
  171. CERT_DestroyUserNotice(userNotice);
  172. return SECSuccess;
  173. }
  174. return SECFailure; /* caller will print this value */
  175. }
  176. static SECStatus
  177. secu_PrintPolicyQualifier(FILE *out,CERTPolicyQualifier *policyQualifier,
  178. char *msg,int level)
  179. {
  180. SECStatus rv;
  181. SECItem * qualifierValue = &policyQualifier->qualifierValue;
  182. SECU_PrintObjectID(out, &policyQualifier->qualifierID ,
  183. "Policy Qualifier Name", level);
  184. if (!qualifierValue->data) {
  185. SECU_Indent(out, level);
  186. fprintf(out,"Error: missing qualifier\n");
  187. } else
  188. switch (policyQualifier->oid) {
  189. case SEC_OID_PKIX_USER_NOTICE_QUALIFIER:
  190. rv = secu_PrintUserNoticeQualifier(out, qualifierValue, msg, level);
  191. if (SECSuccess == rv)
  192. break;
  193. /* fall through on error */
  194. case SEC_OID_PKIX_CPS_POINTER_QUALIFIER:
  195. default:
  196. SECU_PrintAny(out, qualifierValue, "Policy Qualifier Data", level);
  197. break;
  198. }
  199. return SECSuccess;
  200. }
  201. static SECStatus
  202. secu_PrintPolicyInfo(FILE *out,CERTPolicyInfo *policyInfo,char *msg,int level)
  203. {
  204. CERTPolicyQualifier **policyQualifiers;
  205. policyQualifiers = policyInfo->policyQualifiers;
  206. SECU_PrintObjectID(out, &policyInfo->policyID , "Policy Name", level);
  207. while (policyQualifiers && *policyQualifiers != NULL) {
  208. secu_PrintPolicyQualifier(out,*policyQualifiers,"",level+1);
  209. policyQualifiers++;
  210. }
  211. return SECSuccess;
  212. }
  213. void
  214. SECU_PrintPolicy(FILE *out, SECItem *value, char *msg, int level)
  215. {
  216. CERTCertificatePolicies *policies = NULL;
  217. CERTPolicyInfo **policyInfos;
  218. if (msg) {
  219. SECU_Indent(out, level);
  220. fprintf(out,"%s: \n",msg);
  221. level++;
  222. }
  223. policies = secu_DecodeCertificatePoliciesExtension(value);
  224. if (policies == NULL) {
  225. SECU_PrintAny(out, value, "Invalid Policy Data", level);
  226. return;
  227. }
  228. policyInfos = policies->policyInfos;
  229. while (policyInfos && *policyInfos != NULL) {
  230. secu_PrintPolicyInfo(out,*policyInfos,"",level);
  231. policyInfos++;
  232. }
  233. CERT_DestroyCertificatePoliciesExtension(policies);
  234. }
  235. void
  236. SECU_PrintPrivKeyUsagePeriodExtension(FILE *out, SECItem *value,
  237. char *msg, int level)
  238. {
  239. CERTPrivKeyUsagePeriod * prd;
  240. PLArenaPool * arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
  241. if ( !arena ) {
  242. goto loser;
  243. }
  244. prd = CERT_DecodePrivKeyUsagePeriodExtension(arena, value);
  245. if (!prd) {
  246. goto loser;
  247. }
  248. if (prd->notBefore.data) {
  249. SECU_PrintGeneralizedTime(out, &prd->notBefore, "Not Before", level);
  250. }
  251. if (prd->notAfter.data) {
  252. SECU_PrintGeneralizedTime(out, &prd->notAfter, "Not After ", level);
  253. }
  254. if (!prd->notBefore.data && !prd->notAfter.data) {
  255. SECU_Indent(out, level);
  256. fprintf(out, "Error: notBefore or notAfter MUST be present.\n");
  257. loser:
  258. SECU_PrintAny(out, value, msg, level);
  259. }
  260. if (arena) {
  261. PORT_FreeArena(arena, PR_FALSE);
  262. }
  263. }