1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 
5 #if 0
6 
7 //Template for new classes
8 
9 /* ========================================================================== */
10 /* ============================= NewType Class ============================== */
11 /* ========================================================================== */
12 
13 /* ============================ Attribute Access ============================ */
14 
15 static PyObject *
16 NewType_get_classproperty(NewType *self, void *closure)
17 {
18     TraceMethodEnter(self);
19 
20     return NULL;
21 }
22 
23 static int
24 NewType_set_classproperty(NewType *self, PyObject *value, void *closure)
25 {
26     TraceMethodEnter(self);
27 
28     if (value == NULL) {
29         PyErr_SetString(PyExc_TypeError, "Cannot delete the classproperty attribute");
30         return -1;
31     }
32 
33     if (!PyBaseString_Check(value)) {
34         PyErr_Format(PyExc_TypeError, "classproperty must be a string, not %.200s",
35                      Py_TYPE(value)->tp_name);
36         return -1;
37     }
38 
39     return 0;
40 }
41 
42 static
43 PyGetSetDef NewType_getseters[] = {
44     {"classproperty", (getter)NewType_get_classproperty,    (setter)NewType_set_classproperty,
45      "xxx", NULL},
46     {NULL}  /* Sentinel */
47 };
48 
49 static PyMemberDef NewType_members[] = {
50     {NULL}  /* Sentinel */
51 };
52 
53 /* ============================== Class Methods ============================= */
54 
55 static PyObject *
56 NewType_format_lines(NewType *self, PyObject *args, PyObject *kwds)
57 {
58     static char *kwlist[] = {"level", NULL};
59     int level = 0;
60     PyObject *lines = NULL;
61     PyObject *obj1 = NULL;
62 
63     TraceMethodEnter(self);
64 
65     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:format_lines", kwlist, &level))
66         return NULL;
67 
68     if ((lines = PyList_New(0)) == NULL) {
69         return NULL;
70     }
71 
72     return lines;
73  fail:
74     Py_XDECREF(obj1);
75     Py_XDECREF(lines);
76     return NULL;
77 }
78 
79 static PyObject *
80 NewType_format(NewType *self, PyObject *args, PyObject *kwds)
81 {
82     TraceMethodEnter(self);
83 
84     return format_from_lines((format_lines_func)NewType_format_lines, (PyObject *)self, args, kwds);
85 }
86 
87 static PyObject *
88 NewType_str(NewType *self)
89 {
90     PyObject *py_formatted_result = NULL;
91 
92     TraceMethodEnter(self);
93 
94     py_formatted_result =  NewType_format(self, empty_tuple, NULL);
95     return py_formatted_result;
96 
97 }
98 
99 PyDoc_STRVAR(NewType_func_name_doc,
100 "func_name() -> \n\
101 \n\
102 :Parameters:\n\
103     arg1 : object\n\
104         xxx\n\
105 \n\
106 xxx\n\
107 ");
108 
109 static PyObject *
110 NewType_func_name(PyObject *self, PyObject *args, PyObject *kwds)
111 {
112     static char *kwlist[] = {"arg1", NULL};
113     PyObject *arg;
114 
115     TraceMethodEnter(self);
116 
117     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|i:func_name", kwlist,
118                                      &arg))
119         return NULL;
120 
121     return NULL;
122 }
123 
124 static PyMethodDef NewType_methods[] = {
125     {"format_lines", (PyCFunction)NewType_format_lines,   METH_VARARGS|METH_KEYWORDS, generic_format_lines_doc},
126     {"format",       (PyCFunction)NewType_format,         METH_VARARGS|METH_KEYWORDS, generic_format_doc},
127     {"func_name",    (PyCFunction)NewType_func_name, METH_VARARGS|METH_KEYWORDS, NewType_func_name_doc},
128     {NULL, NULL}  /* Sentinel */
129 };
130 
131 /* =========================== Sequence Protocol ============================ */
132 static Py_ssize_t
133 NSSType_list_count(NSSType *head)
134 {
135     NSSType *cur;
136     Py_ssize_t count;
137 
138     count = 0;
139     if (!head) {
140         return count;
141     }
142 
143     cur = head;
144     do {
145         count++;
146         cur = NSSType_Next(cur);
147     } while (cur != head);
148 
149     return count;
150 }
151 
152 static Py_ssize_t
153 NewType_length(NewType *self)
154 {
155     if (!self->name) {
156         PyErr_Format(PyExc_ValueError, "%s is uninitialized", Py_TYPE(self)->tp_name);
157         return -1;
158     }
159 
160     return NSSType_list_count(self->name);
161 }
162 
163 static PyObject *
164 NewType_item(NewType *self, register Py_ssize_t i)
165 {
166     NSSType *head, *cur;
167     Py_ssize_t index;
168 
169     if (!self->name) {
170         return PyErr_Format(PyExc_ValueError, "%s is uninitialized", Py_TYPE(self)->tp_name);
171     }
172 
173     index = 0;
174     cur = head = self->name;
175     do {
176         cur = NSSType_Next(cur);
177         if (i == index) {
178             return NewType_new_from_NSSType(cur);
179         }
180         index++;
181     } while (cur != head);
182 
183     PyErr_SetString(PyExc_IndexError, "NewType index out of range");
184     return NULL;
185 }
186 
187 
188 /* =========================== Class Construction =========================== */
189 
190 static PyObject *
191 NewType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
192 {
193     NewType *self;
194 
195     TraceObjNewEnter(type);
196 
197     if ((self = (NewType *)type->tp_alloc(type, 0)) == NULL) {
198         return NULL;
199     }
200 
201     TraceObjNewLeave(self);
202     return (PyObject *)self;
203 }
204 
205 Py_TPFLAGS_HAVE_GC
206 static int
207 NewType_traverse(NewType *self, visitproc visit, void *arg)
208 {
209     TraceMethodEnter(self);
210 
211     Py_VISIT(self->obj);
212     return 0;
213 }
214 
215 static int
216 NewType_clear(NewType* self)
217 {
218     TraceMethodEnter(self);
219 
220     Py_CLEAR(self->obj);
221     return 0;
222 }
223 
224 static void
225 NewType_dealloc(NewType* self)
226 {
227     TraceMethodEnter(self);
228 
229     NewType_clear(self);
230     Py_TYPE(self)->tp_free((PyObject*)self);
231 }
232 
233 PyDoc_STRVAR(NewType_doc,
234 "NewType(obj)\n\
235 \n\
236 :Parameters:\n\
237     obj : xxx\n\
238 \n\
239 An object representing NewType.\n\
240 ");
241 
242 static int
243 NewType_init(NewType *self, PyObject *args, PyObject *kwds)
244 {
245     static char *kwlist[] = {"arg", NULL};
246     PyObject *arg;
247 
248     TraceMethodEnter(self);
249 
250     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|i:NewType", kwlist,
251                                      &arg))
252         return -1;
253 
254     return 0;
255 }
256 
257 static PySequenceMethods NewType_as_sequence = {
258     (lenfunc)NewType_length,		/* sq_length */
259     0,						/* sq_concat */
260     0,						/* sq_repeat */
261     (ssizeargfunc)NewType_item,		/* sq_item */
262     0,						/* sq_slice */
263     0,						/* sq_ass_item */
264     0,						/* sq_ass_slice */
265     0,						/* sq_contains */
266     0,						/* sq_inplace_concat */
267     0,						/* sq_inplace_repeat */
268 };
269 
270 static PyTypeObject NewTypeType = {
271     PyVarObject_HEAD_INIT(NULL, 0)
272     "nss.nss.NewType",				/* tp_name */
273     sizeof(NewType),				/* tp_basicsize */
274     0,						/* tp_itemsize */
275     (destructor)NewType_dealloc,		/* tp_dealloc */
276     0,						/* tp_print */
277     0,						/* tp_getattr */
278     0,						/* tp_setattr */
279     0,						/* tp_compare */
280     0,						/* tp_repr */
281     0,						/* tp_as_number */
282     0,						/* tp_as_sequence */
283     0,						/* tp_as_mapping */
284     0,						/* tp_hash */
285     0,						/* tp_call */
286     (reprfunc)NewType_str,			/* tp_str */
287     0,						/* tp_getattro */
288     0,						/* tp_setattro */
289     0,						/* tp_as_buffer */
290     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,	/* tp_flags */
291     NewType_doc,				/* tp_doc */
292     (traverseproc)0,				/* tp_traverse */
293     (inquiry)0,					/* tp_clear */
294     0,						/* tp_richcompare */
295     0,						/* tp_weaklistoffset */
296     0,						/* tp_iter */
297     0,						/* tp_iternext */
298     NewType_methods,				/* tp_methods */
299     NewType_members,				/* tp_members */
300     NewType_getseters,				/* tp_getset */
301     0,						/* tp_base */
302     0,						/* tp_dict */
303     0,						/* tp_descr_get */
304     0,						/* tp_descr_set */
305     0,						/* tp_dictoffset */
306     (initproc)NewType_init,			/* tp_init */
307     0,						/* tp_alloc */
308     NewType_new,				/* tp_new */
309 };
310 
311 static PyObject *
312 NewType_new_from_NSSType(NSSType *id)
313 {
314     NewType *self = NULL;
315 
316     TraceObjNewEnter(NULL);
317 
318     if ((self = (NewType *) NewTypeType.tp_new(&NewTypeType, NULL, NULL)) == NULL) {
319         return NULL;
320     }
321 
322     TraceObjNewLeave(self);
323     return (PyObject *) self;
324 }
325 
326 #endif
327 
328 // FIXME: should we be calling these?
329 // SECKEY_DestroyEncryptedPrivateKeyInfo
330 // SECKEY_DestroyPrivateKey	   SECKEY_DestroyPrivateKeyInfo
331 // SECKEY_DestroyPrivateKeyList	   SECKEY_DestroyPublicKey
332 // SECKEY_DestroyPublicKeyList	   SECKEY_DestroySubjectPublicKeyInfo
333 
334 #define PY_SSIZE_T_CLEAN
335 #include "Python.h"
336 #include "structmember.h"
337 #include "datetime.h"
338 
339 #include "py_nspr_common.h"
340 #define NSS_NSS_MODULE
341 #include "py_nss.h"
342 #include "py_shared_doc.h"
343 #include "py_nspr_error.h"
344 
345 #include "secder.h"
346 #include "sechash.h"
347 #include "certdb.h"
348 #include "hasht.h"
349 #include "nssb64.h"
350 #include "secport.h"
351 #include "secerr.h"
352 #include "secpkcs5.h"
353 #include "p12plcy.h"
354 #include "ciferfam.h"
355 #include "ocsp.h"
356 
357 #if (NSS_VMAJOR > 3) || (NSS_VMAJOR == 3 && NSS_VMINOR >= 13)
358 #define HAVE_RSA_PSS
359 #endif
360 
361 #define MAX_AVAS 10
362 #define MAX_RDNS 10
363 
364 #ifdef DEBUG
365 #include "py_traceback.h"
366 
367 static void
368 print_cert(CERTCertificate *cert, const char *format, ...) __attribute__ ((format (printf, 2, 3)));
369 
370 static void
print_cert(CERTCertificate * cert,const char * format,...)371 print_cert(CERTCertificate *cert, const char *format, ...)
372 {
373     va_list va;
374     char *subject;
375 
376     if (cert == NULL) {
377         printf("Certificate was null\n");
378         return;
379     }
380 
381     subject = CERT_NameToAscii(&cert->subject);
382 
383     if (format) {
384         va_start(va, format);
385         vprintf(format, va);
386         va_end(va);
387         printf(" subject %s\n", subject);
388     } else {
389         printf("Certificate subject: %s\n", subject);
390     }
391 
392     PORT_Free(subject);
393     nss_DumpCertificateCacheInfo();
394     print_traceback();
395 }
396 #endif
397 
398 /* FIXME: convert all equality tests to Py_None to PyNone_Check() */
399 
400 //FIXME, should be in py_nss.h
401 #define PyAVA_Check(op)  PyObject_TypeCheck(op, &AVAType)
402 #define PyRDN_Check(op)  PyObject_TypeCheck(op, &RDNType)
403 #define PyDN_Check(op) PyObject_TypeCheck(op, &DNType)
404 
405 #define PyRSAGenParams_Check(op) PyObject_TypeCheck(op, &RSAGenParamsType)
406 #define PyKEYPQGParams_Check(op) PyObject_TypeCheck(op, &KEYPQGParamsType)
407 #define PyCertVerifyLog_Check(op) PyObject_TypeCheck(op, &CertVerifyLogType)
408 
409 
410 #define BIT_FLAGS_TO_LIST_PROLOGUE()                                    \
411     PyObject *py_flags = NULL;                                          \
412     PyObject *py_flag = NULL;                                           \
413                                                                         \
414     switch(repr_kind) {                                                 \
415     case AsEnum:                                                        \
416     case AsEnumName:                                                    \
417     case AsEnumDescription:                                             \
418         break;                                                          \
419     default:                                                            \
420         PyErr_Format(PyExc_ValueError, "Unsupported representation kind (%d)", repr_kind); \
421         return NULL;                                                    \
422     }                                                                   \
423                                                                         \
424     if ((py_flags = PyList_New(0)) == NULL)                             \
425         return NULL;
426 
427 
428 
429 #define BIT_FLAGS_TO_LIST(enum, description)                            \
430 {                                                                       \
431     if (flags & enum) {                                                 \
432         flags &= ~enum;                                                 \
433         switch(repr_kind) {                                             \
434         case AsEnum:                                                    \
435             py_flag = PyLong_FromLong(enum);                            \
436             break;                                                      \
437         case AsEnumName:                                                \
438             py_flag = PyUnicode_FromString(#enum);                      \
439             break;                                                      \
440         case AsEnumDescription:                                         \
441             py_flag = PyUnicode_FromString(description);                \
442             break;                                                      \
443         default:                                                        \
444             PyErr_Format(PyExc_ValueError, "Unsupported representation kind (%d)", repr_kind); \
445             Py_DECREF(py_flags);                                        \
446             return NULL;                                                \
447         }                                                               \
448 	if (py_flag == NULL) {                                          \
449             Py_DECREF(py_flags);                                        \
450             return NULL;                                                \
451         }                                                               \
452         PyList_Append(py_flags, py_flag);                               \
453 	Py_DECREF(py_flag);                                             \
454     }                                                                   \
455 }
456 
457 #define BIT_FLAGS_TO_LIST_EPILOGUE()                                    \
458 {                                                                       \
459     if (flags) {                                                        \
460         if ((py_flag = PyUnicode_FromFormat("unknown bit flags %#x", flags)) == NULL) { \
461             Py_DECREF(py_flags);                                        \
462             return NULL;                                                \
463         }                                                               \
464         PyList_Append(py_flags, py_flag);                               \
465 	Py_DECREF(py_flag);                                             \
466     }                                                                   \
467                                                                         \
468     if (PyList_Sort(py_flags) == -1) {                                  \
469             Py_DECREF(py_flags);                                        \
470             return NULL;                                                \
471     }                                                                   \
472                                                                         \
473     return py_flags;                                                    \
474 }
475 
476 /* ========================================================================== */
477 /* ========================= Formatting Utilities =========================== */
478 /* ========================================================================== */
479 
480 
481 static PyObject *
482 line_fmt_tuple(int level, const char *label, PyObject *py_value);
483 
484 static PyObject *
485 make_line_fmt_tuples(int level, PyObject *src);
486 
487 static PyObject *
488 py_make_line_fmt_tuples(PyObject *self, PyObject *args, PyObject *kwds);
489 
490 static PyObject *
491 fmt_label(int level, char *label);
492 
493 static PyObject *
494 format_from_lines(format_lines_func formatter, PyObject *self, PyObject *args, PyObject *kwds);
495 
496 static PyObject *
497 py_indented_format(PyObject *self, PyObject *args, PyObject *kwds);
498 
499 /* Steals reference to obj_str */
500 static PyObject *
line_fmt_tuple(int level,const char * label,PyObject * py_value)501 line_fmt_tuple(int level, const char *label, PyObject *py_value)
502 {
503     Py_ssize_t tuple_size, i;
504     PyObject *fmt_tuple = NULL;
505     PyObject *py_label = NULL;
506     PyObject *py_value_str = NULL;
507 
508     tuple_size = 1;             /* always have level */
509 
510     if (label) {
511         tuple_size++;
512         if ((py_label = PyUnicode_FromFormat("%s:", label)) == NULL) {
513             return NULL;
514         }
515     }
516 
517     if (py_value) {
518         tuple_size++;
519         if (PyBaseString_Check(py_value)) {
520             py_value_str = PyUnicode_from_basestring(py_value);
521         } else {
522             if ((py_value_str = PyObject_String(py_value)) == NULL) {
523                 return NULL;
524             }
525         }
526     }
527 
528     if ((fmt_tuple = PyTuple_New(tuple_size)) == NULL) {
529         return NULL;
530     }
531 
532     i = 0;
533     PyTuple_SetItem(fmt_tuple, i++, PyLong_FromLong(level));
534 
535     if (py_label) {
536         PyTuple_SetItem(fmt_tuple, i++, py_label);
537     }
538 
539     if (py_value_str) {
540         PyTuple_SetItem(fmt_tuple, i++, py_value_str);
541     }
542 
543     return fmt_tuple;
544 }
545 
546 static PyObject *
make_line_fmt_tuples(int level,PyObject * src)547 make_line_fmt_tuples(int level, PyObject *src)
548 {
549     PyObject *lines = NULL;
550     PyObject *obj = NULL;
551     PyObject *fmt_tuple = NULL;
552     PyObject *seq = NULL;
553     Py_ssize_t n_objs, i;
554 
555     if (PyList_Check(src) || PyTuple_Check(src)) {
556         seq = src;
557         n_objs = PySequence_Size(seq);
558         Py_INCREF(seq);
559     } else {
560         obj = src;
561         Py_INCREF(obj);
562         n_objs = 1;
563     }
564 
565     if ((lines = PyList_New(n_objs)) == NULL) {
566         goto exit;
567     }
568 
569     if (seq) {
570         for (i = 0; i < n_objs; i++) {
571             if ((obj = PySequence_GetItem(seq, i)) == NULL) { /* new reference */
572                 Py_DECREF(lines);
573                 goto exit;
574             }
575             if ((fmt_tuple = line_fmt_tuple(level, NULL, obj)) == NULL) {
576                 Py_DECREF(lines);
577                 goto exit;
578             }
579             PyList_SetItem(lines, i, fmt_tuple);
580             Py_CLEAR(obj);
581         }
582     } else {
583         if ((fmt_tuple = line_fmt_tuple(level, NULL, obj)) == NULL) {
584             Py_DECREF(lines);
585             goto exit;
586         }
587         PyList_SetItem(lines, 0, fmt_tuple);
588     }
589 
590  exit:
591     Py_XDECREF(obj);
592     Py_XDECREF(seq);
593     return lines;
594 }
595 
596 PyDoc_STRVAR(py_make_line_fmt_tuples_doc,
597 "make_line_fmt_tuples(level, obj) -> [(level, str), ...]\n\
598 \n\
599 :Parameters:\n\
600     obj : object\n\
601         If obj is a tuple or list then each member will be wrapped\n\
602         in a 2-tuple of (level, str). If obj is a scalar object\n\
603         then obj will be wrapped in a 2-tuple of (level, obj)\n\
604     level : integer\n\
605         Initial indentation level, all subsequent indents are relative\n\
606         to this starting level.\n\
607 \n\
608 Return a list of line formatted tuples sutible to passing to\n\
609 `indented_format()`. Each tuple consists of a integer\n\
610 level value and a string object. This is equivalent to:\n\
611 [(level, str(x)) for x in obj].\n\
612 As a special case convenience if obj is a scalar object (i.e.\n\
613 not a list or tuple) then [(level, str(obj))] will be returned.\n\
614 ");
615 
616 static PyObject *
py_make_line_fmt_tuples(PyObject * self,PyObject * args,PyObject * kwds)617 py_make_line_fmt_tuples(PyObject *self, PyObject *args, PyObject *kwds)
618 {
619     static char *kwlist[] = {"level", "obj", NULL};
620     int level = 0;
621     PyObject *obj;
622 
623     TraceMethodEnter(self);
624 
625     if (!PyArg_ParseTupleAndKeywords(args, kwds, "iO:make_line_fmt_tuples", kwlist,
626                                      &level, &obj))
627         return NULL;
628 
629     return make_line_fmt_tuples(level, obj);
630 }
631 
632 static PyObject *
fmt_label(int level,char * label)633 fmt_label(int level, char *label)
634 {
635     return line_fmt_tuple(level, label, NULL);
636 }
637 
638 static PyObject *
format_from_lines(format_lines_func formatter,PyObject * self,PyObject * args,PyObject * kwds)639 format_from_lines(format_lines_func formatter, PyObject *self, PyObject *args, PyObject *kwds)
640 {
641     static char *kwlist[] = {"level", "indent_len",  NULL};
642     int level = 0;
643     int indent_len = 4;
644     PyObject *py_lines = NULL;
645     PyObject *py_formatted_result = NULL;
646     PyObject *tmp_args = NULL;
647 
648     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ii:format", kwlist, &level, &indent_len))
649         return NULL;
650 
651     if ((tmp_args = Py_BuildValue("(i)", level)) == NULL) {
652         goto fail;
653     }
654     if ((py_lines = formatter(self, tmp_args, NULL)) == NULL) {
655         goto fail;
656     }
657     Py_CLEAR(tmp_args);
658 
659     if ((tmp_args = Py_BuildValue("Oi", py_lines, indent_len)) == NULL) {
660         goto fail;
661     }
662     if ((py_formatted_result = py_indented_format(NULL, tmp_args, NULL)) == NULL) {
663         goto fail;
664     }
665 
666     Py_DECREF(tmp_args);
667     Py_DECREF(py_lines);
668     return py_formatted_result;
669 
670  fail:
671     Py_XDECREF(tmp_args);
672     Py_XDECREF(py_lines);
673     return NULL;
674 }
675 
676 PyDoc_STRVAR(py_indented_format_doc,
677 "indented_format(line_fmt_tuples, indent_len=4) -> string\n\
678 \n\
679 The function supports the display of complex objects which may be\n\
680 composed of other complex objects. There is often a need to output\n\
681 section headers or single strings and lists of <attribute,value> pairs\n\
682 (the attribute in this discussion is called a label), or even blank\n\
683 lines. All of these items should line up in columns at different\n\
684 indentation levels in order to visually see the structure.\n\
685 \n\
686 It would not be flexible enough to have object formatting routines\n\
687 which simply returned a single string with all the indentation and\n\
688 formatting pre-applied. The indentation width may not be what is\n\
689 desired. Or more importantly you might not be outputting to text\n\
690 display. It might be a GUI which desires to display the\n\
691 information. Most GUI's want to handle each string seperately and\n\
692 control indentation and the visibility of each item (e.g. a tree\n\
693 control).\n\
694 \n\
695 At the same time we want to satisfy the need for easy and simple text\n\
696 output. This routine will do that, e.g.:\n\
697 \n\
698     print indented_format(obj.format_lines())\n\
699 \n\
700 To accomodate necessary flexibility the object formatting methods\n\
701 (format_lines()) return a list of tuples. Each tuple represents a\n\
702 single line with the first tuple item being the indentation level for\n\
703 the line. There may be 0,1 or 2 additional strings in the tuple which\n\
704 are to be output on the line. A single string are usually one of two\n\
705 things, either a section header or data that has been continuted onto\n\
706 multiple lines. Two strings usually represent a <attribute,value> pair\n\
707 with the first string being a label (e.g. attribute name).\n\
708 \n\
709 Each tuple may be:\n\
710 \n\
711     (int,)\n\
712         1-value tuple, no strings, e.g. blank line.\n\
713 \n\
714     (int, string)\n\
715         2-value tuple, output string at indent level.\n\
716 \n\
717     (int, string, string)\n\
718         3-value tuple, first string is a label, second string is a\n\
719         value.  Starting at the indent level output the label, then\n\
720         follow with the value. By keeping the label separate from the\n\
721         value the ouput formatter may elect to align the values in\n\
722         vertical columns for adjacent lines.\n\
723 \n\
724 Example::\n                                     \
725 \n\
726     # This list of tuples,\n\
727 \n\
728     [(0, 'Constraints'),\n\
729      (1, 'min:', '0')\n\
730      (1, 'max:', '100'),\n\
731      (1, 'Filter Data'),\n\
732      (2, 'ab bc de f0 12 34 56 78 9a bc de f0')\n\
733      (2, '12 34 56 78 9a bc de f0 12 34 56 78')\n\
734     ]\n\
735 \n\
736     # would product this output\n\
737 \n\
738     Constraints\n\
739         min: 0\n\
740         max: 100\n\
741         Filter Data:\n\
742            ab bc de f0 12 34 56 78 9a bc de f0\n\
743            12 34 56 78 9a bc de f0 12 34 56 78\n\
744 \n\
745 :Parameters:\n\
746     line_fmt_tuples : [(level, ...),...]\n\
747         A list of tuples. First tuple value is the indentation level\n\
748         followed by optional strings for the line.\n\
749     indent_len : int\n\
750         Number of space characters repeated for each level and\n\
751         prepended to the line string.\n\
752 \n\
753 ");
754 
755 static PyObject *
py_indented_format(PyObject * self,PyObject * args,PyObject * kwds)756 py_indented_format(PyObject *self, PyObject *args, PyObject *kwds)
757 {
758     typedef struct {
759         Py_ssize_t indent_len;
760         Py_ssize_t label_len;
761         Py_ssize_t value_len;
762         Py_ssize_t justification_len;
763     } LineInfo;
764 
765 
766     static char *kwlist[] = {"lines_pairs", "indent_len", NULL};
767     PyObject *py_lines = NULL;
768     long line_level = 0;
769     int indent_len = 4;
770     int cur_indent_len = 0;
771     char *src=NULL, *dst=NULL;
772     Py_ssize_t num_lines, tuple_len;
773     char *label = NULL;
774     char *value = NULL;
775     Py_ssize_t label_len, value_len, justification_len, max_align;
776     char *src_end = NULL;
777     PyObject *py_line_fmt_tuple = NULL;
778     PyObject *py_level = NULL;
779     PyObject *py_label = NULL;
780     PyObject *py_value = NULL;
781     PyObject *py_string_utf8 = NULL;
782     Py_ssize_t cur_formatted_line_len;
783     PyObject *py_formatted_str = NULL;
784     PyObject *py_unicode_formatted_str = NULL;
785     Py_ssize_t formatted_str_len;
786     char *formatted_str;
787     Py_ssize_t i, j, k;
788     LineInfo *line_info = NULL;
789 
790     /*
791      * Implementation note:
792      *
793      * This was originally coded to produce utf-8 strings in
794      * Py2. During the Py2 to Py3 porting when all strings were
795      * converted to unicode it was observed the conversion to utf-8
796      * and string building in utf-8 done in this function could be
797      * avoided and instead characters could be defined as
798      * PY_UNICODE_TYPE and all size computation and character movement
799      * be done on the scalar PY_UNICODE_TYPE character type.
800      *
801      * But PEP 393 "Flexible String Representation" clearly warns
802      * against extension modules assuming a fixed size for a unicode
803      * character and offers this suggestion:
804      *
805      *     Applications are encouraged to phase out reliance on a
806      *     specific internal representation if possible. As
807      *     interaction with other libraries will often require some
808      *     sort of internal representation, the specification chooses
809      *     UTF-8 as the recommended way of exposing strings to C code.
810      *
811      * Thus the original stategy of converting all strings to utf-8,
812      * computing their size and subsequently copying them is
813      * retained. The only difference is the final utf-8 string is
814      * decoded into unicode prior to returning it. This protects us
815      * against future changes to the internal represention of a
816      * unicode character.
817      */
818 
819     TraceMethodEnter(self);
820 
821     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|i:indented_format", kwlist,
822                                      &PyList_Type, &py_lines, &indent_len))
823         return NULL;
824 
825     num_lines = PyList_Size(py_lines);
826 
827     /*
828      * Because we interrogate the length of the various strings
829      * multiple times in the various loops we don't want to repeatedly
830      * dereference and query the Pyton objects each time. So we
831      * allocate an array to cache the information for efficency
832      * purposes.
833      */
834 
835     if ((line_info = PyMem_Malloc(num_lines*sizeof(LineInfo))) == NULL) {
836         return PyErr_NoMemory();
837     }
838 
839     /*
840      * Step 1: Scan all the lines and get the string sizes.  Do all
841      * error checking in this loop so we don't have to do it again
842      * later. Cache the size information for faster access in
843      * subseqent loops.
844      */
845 
846     for (i = 0; i < num_lines; i++) {
847         py_label = NULL;
848         label = NULL;
849         label_len = 0;
850 
851         py_value = NULL;
852         value = NULL;
853         value_len = 0;
854 
855         py_line_fmt_tuple = PyList_GetItem(py_lines, i);
856         if (!PyTuple_Check(py_line_fmt_tuple)) {
857             PyErr_Format(PyExc_TypeError, "line_fmt_tuples[%zd] must be a tuple, not %.200s",
858                          i, Py_TYPE(py_line_fmt_tuple)->tp_name);
859             goto fail;
860         }
861 
862         tuple_len = PyTuple_Size(py_line_fmt_tuple);
863 
864         if (tuple_len < 1 || tuple_len > 3) {
865             PyErr_Format(PyExc_TypeError, "line_fmt_tuples[%zd] tuple must have 1-3 items, not %zd items",
866                          i, tuple_len);
867             goto fail;
868         }
869 
870         py_level = PyTuple_GetItem(py_line_fmt_tuple, 0);
871         if (tuple_len == 2) {
872             py_label = PyTuple_GetItem(py_line_fmt_tuple, 1);
873         } else if (tuple_len == 3) {
874             py_label = PyTuple_GetItem(py_line_fmt_tuple, 1);
875             py_value = PyTuple_GetItem(py_line_fmt_tuple, 2);
876         }
877 
878         if (!PyInteger_Check(py_level)) {
879             PyErr_Format(PyExc_TypeError, "item[0] in the tuple at line_fmt_tuples[%zd] list must be an integer, not %.200s",
880                          i, Py_TYPE(py_level)->tp_name);
881             goto fail;
882         }
883         line_level = PyLong_AsLong(py_level);
884         if (line_level < 0) {
885             PyErr_Format(PyExc_TypeError, "item[0] in the tuple at line_fmt_tuples[%zd] list must be a non-negative integer, not %ld",
886                          i, line_level);
887             goto fail;
888         }
889 
890         label_len = value_len = 0;
891         if (py_label) {
892             if ((py_string_utf8 = PyBaseString_UTF8(py_label, "label")) == NULL) {
893                 PyErr_Format(PyExc_TypeError, "item[1] in the tuple at line_fmt_tuples[%zd] list must be a string, not %.200s",
894                              i, Py_TYPE(py_label)->tp_name);
895                 goto fail;
896             }
897             if (PyBytes_AsStringAndSize(py_string_utf8, &label, &label_len) == -1) {
898                 goto fail;
899             }
900         }
901         Py_CLEAR(py_string_utf8);
902 
903         if (py_value) {
904             if ((py_string_utf8 = PyBaseString_UTF8(py_value, "value")) == NULL) {
905                 PyErr_Format(PyExc_TypeError, "item[2] in the tuple at line_fmt_tuples[%zd] list must be a string, not %.200s",
906                              i, Py_TYPE(py_value)->tp_name);
907                 goto fail;
908             }
909             if (PyBytes_AsStringAndSize(py_string_utf8, &value, &value_len) == -1) {
910                 goto fail;
911             }
912         }
913         Py_CLEAR(py_string_utf8);
914 
915         /* Cache the length information */
916         line_info[i].label_len = label_len;
917         line_info[i].value_len = value_len;
918         line_info[i].justification_len = 0;
919         line_info[i].indent_len = line_level * indent_len;
920     }
921 
922     /*
923      * Step 2: Locate labels and values that appear on consecutive
924      * lines at the same indentation level. Compute the alignment for
925      * values such that values all line up in the same column.
926      *
927      * We consider only lines that have both a label and a value for
928      * the purpose of computing the alignment, if a line has only a
929      * label we ignore it when establishing value alignment.
930      *
931      * A change in the indendation level resets the alignment.
932      */
933     for (i = 0; i < num_lines;) {
934         cur_indent_len = line_info[i].indent_len;
935         if (line_info[i].value_len) {
936             max_align = line_info[i].label_len;
937         } else {
938             max_align = 0;
939         }
940 
941         /*
942          * Search forward for consecutive lines that share the same
943          * indendation level.  If the line has value then use it's
944          * label to compute the maximum width of all labels in this
945          * group of lines.
946          */
947         for (j = i+1; j < num_lines && cur_indent_len == line_info[j].indent_len; j++) {
948             if (line_info[j].value_len) {
949                 if (line_info[j].label_len > max_align) {
950                     max_align = line_info[j].label_len;
951                 }
952             }
953         }
954 
955         /*
956          * Now we know the maximum width of all labels in this group
957          * of lines.  We always provide 1 space between a label and
958          * it's value so we add 1 to the maximum label width, this
959          * becomes our column for value alignment.
960          *
961          * If there were no values in this group of lines max_align
962          * will be zero and we won't be doing any value alignment.
963          */
964         if (max_align) {
965             max_align += 1;
966         }
967 
968         /*
969          * Now that we know the alignment column go back and compute
970          * how much space to add at the end of each label to hit the
971          * alignment column when we append the value.
972          */
973         for (k = i; k < j; k++) {
974             if (line_info[k].value_len) { /* Only justify if there is a value */
975                 line_info[k].justification_len = max_align - line_info[k].label_len;
976             }
977         }
978 
979         /* This group of lines is processed, advance to the next group. */
980         i = j;
981     }
982 
983     /*
984      * Step 3: We now know how many characters every line consumes,
985      * compute the total buffer size required and allocate it.
986      */
987     formatted_str_len = 0;
988     for (i = 0; i < num_lines; i++) {
989         cur_formatted_line_len = line_info[i].indent_len +
990                                  line_info[i].label_len +
991                                  line_info[i].justification_len +
992                                  line_info[i].value_len + 1; /* +1 for newline */
993         formatted_str_len += cur_formatted_line_len;
994     }
995 
996     if (num_lines > 0) formatted_str_len -= 1; /* last line doesn't get a new line appended */
997     if ((py_formatted_str = PyBytes_FromStringAndSize(NULL, formatted_str_len)) == NULL) {
998         goto fail;
999     }
1000 
1001     formatted_str = PyBytes_AS_STRING(py_formatted_str);
1002     dst = formatted_str;
1003 
1004     /*
1005      * Step 4: For each line: Insert the indent. If it has a label
1006      * insert the label. If it has a value insert the justification to
1007      * align the values, then insert the value. Finally append a
1008      * newline (except for the last line).
1009      */
1010     for (i = 0; i < num_lines; i++) {
1011         py_label = NULL;
1012         label = NULL;
1013 
1014         py_value = NULL;
1015         value = NULL;
1016 
1017         py_line_fmt_tuple = PyList_GetItem(py_lines, i);
1018 
1019         cur_indent_len = line_info[i].indent_len;
1020         label_len = line_info[i].label_len;
1021         value_len = line_info[i].value_len;
1022         justification_len = line_info[i].justification_len;
1023 
1024         /* Insert the indent */
1025         for (j = 0; j < cur_indent_len; j++) *dst++ = ' ';
1026 
1027         /* Insert the label */
1028         if (label_len) {
1029             py_label = PyTuple_GetItem(py_line_fmt_tuple, 1);
1030             py_string_utf8 = PyBaseString_UTF8(py_label, "label");
1031             label = PyBytes_AS_STRING(py_string_utf8);
1032 
1033             for (src = label, src_end = label + label_len; src < src_end; *dst++ = *src++);
1034 
1035             Py_CLEAR(py_string_utf8);
1036         }
1037 
1038         /* Insert the alignment justification for the value */
1039         for (j = 0; j < justification_len; j++) *dst++ = ' ';
1040 
1041         /* Insert the value */
1042         if (value_len) {
1043             py_value = PyTuple_GetItem(py_line_fmt_tuple, 2);
1044             py_string_utf8 = PyBaseString_UTF8(py_value, "value");
1045             value = PyBytes_AS_STRING(py_string_utf8);
1046 
1047             for (src = value, src_end = value + value_len; src < src_end; *dst++ = *src++);
1048 
1049             Py_CLEAR(py_string_utf8);
1050         }
1051 
1052         /* Add a new line, except for the last line */
1053         if (i < num_lines-1)
1054             *dst++ = '\n';
1055     }
1056 
1057     /*
1058      * Done. Sanity check we've written exactly the buffer we allocated.
1059      */
1060     assert(formatted_str + PyBytes_Size(py_formatted_str) == dst);
1061 
1062     /*
1063      * Convert the utf-8 back to unicode for return value.
1064      */
1065     py_unicode_formatted_str = PyUnicode_DecodeUTF8(PyBytes_AS_STRING(py_formatted_str),
1066                                                     PyBytes_Size(py_formatted_str),
1067                                                     NULL);
1068     Py_DECREF(py_formatted_str);
1069     return py_unicode_formatted_str;
1070 
1071  fail:
1072     Py_CLEAR(py_string_utf8);
1073     PyMem_Free(line_info);
1074     Py_XDECREF(py_formatted_str);
1075     return NULL;
1076 }
1077 
1078 /* ========================================================================== */
1079 
1080 /* Copied from mozilla/security/nss/lib/certdb/alg1485.c */
1081 typedef struct DnAvaPropsStr {
1082     const char * name;
1083     unsigned int maxLen; /* max bytes in UTF8 encoded string value */
1084     SECOidTag    oid_tag;
1085     int		 value_type;
1086 } DnAvaProps;
1087 
1088 static const DnAvaProps dn_ava_props[] = {
1089 /* IANA registered type names
1090  * (See: http://www.iana.org/assignments/ldap-parameters)
1091  */
1092 /* RFC 3280, 4630 MUST SUPPORT */
1093     { "CN",             64, SEC_OID_AVA_COMMON_NAME,    SEC_ASN1_UTF8_STRING},
1094     { "ST",            128, SEC_OID_AVA_STATE_OR_PROVINCE,
1095 							SEC_ASN1_UTF8_STRING},
1096     { "O",              64, SEC_OID_AVA_ORGANIZATION_NAME,
1097 							SEC_ASN1_UTF8_STRING},
1098     { "OU",             64, SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME,
1099                                                         SEC_ASN1_UTF8_STRING},
1100     { "dnQualifier", 32767, SEC_OID_AVA_DN_QUALIFIER, SEC_ASN1_PRINTABLE_STRING},
1101     { "C",               2, SEC_OID_AVA_COUNTRY_NAME, SEC_ASN1_PRINTABLE_STRING},
1102     { "serialNumber",   64, SEC_OID_AVA_SERIAL_NUMBER,SEC_ASN1_PRINTABLE_STRING},
1103 
1104 /* RFC 3280, 4630 SHOULD SUPPORT */
1105     { "L",             128, SEC_OID_AVA_LOCALITY,       SEC_ASN1_UTF8_STRING},
1106     { "title",          64, SEC_OID_AVA_TITLE,          SEC_ASN1_UTF8_STRING},
1107     { "SN",             64, SEC_OID_AVA_SURNAME,        SEC_ASN1_UTF8_STRING},
1108     { "givenName",      64, SEC_OID_AVA_GIVEN_NAME,     SEC_ASN1_UTF8_STRING},
1109     { "initials",       64, SEC_OID_AVA_INITIALS,       SEC_ASN1_UTF8_STRING},
1110     { "generationQualifier",
1111                         64, SEC_OID_AVA_GENERATION_QUALIFIER,
1112                                                         SEC_ASN1_UTF8_STRING},
1113 /* RFC 3280, 4630 MAY SUPPORT */
1114     { "DC",            128, SEC_OID_AVA_DC,             SEC_ASN1_IA5_STRING},
1115     { "MAIL",          256, SEC_OID_RFC1274_MAIL,       SEC_ASN1_IA5_STRING},
1116     { "UID",           256, SEC_OID_RFC1274_UID,        SEC_ASN1_UTF8_STRING},
1117 
1118 /* values from draft-ietf-ldapbis-user-schema-05 (not in RFC 3280) */
1119     { "postalAddress", 128, SEC_OID_AVA_POSTAL_ADDRESS, SEC_ASN1_UTF8_STRING},
1120     { "postalCode",     40, SEC_OID_AVA_POSTAL_CODE,    SEC_ASN1_UTF8_STRING},
1121     { "postOfficeBox",  40, SEC_OID_AVA_POST_OFFICE_BOX,SEC_ASN1_UTF8_STRING},
1122     { "houseIdentifier",64, SEC_OID_AVA_HOUSE_IDENTIFIER,SEC_ASN1_UTF8_STRING},
1123 /* end of IANA registered type names */
1124 
1125 /* legacy keywords */
1126     { "E",             128, SEC_OID_PKCS9_EMAIL_ADDRESS,SEC_ASN1_IA5_STRING},
1127 
1128 #if 0 /* removed.  Not yet in any IETF draft or RFC. */
1129     { "pseudonym",      64, SEC_OID_AVA_PSEUDONYM,      SEC_ASN1_UTF8_STRING},
1130 #endif
1131 
1132     { 0,           256, SEC_OID_UNKNOWN                      , 0},
1133 };
1134 
1135 /* ========================================================================== */
1136 typedef struct {
1137     unsigned short len;
1138     char *encoded;
1139 } AsciiEscapes;
1140 
1141 static AsciiEscapes ascii_encoding_table[256] = {
1142     {4, "\\x00"}, /*   0      */    {4, "\\x01"}, /*   1      */
1143     {4, "\\x02"}, /*   2      */    {4, "\\x03"}, /*   3      */
1144     {4, "\\x04"}, /*   4      */    {4, "\\x05"}, /*   5      */
1145     {4, "\\x06"}, /*   6      */    {2, "\\a"  }, /*   7 BELL */
1146     {2, "\\b"  }, /*   8 BS   */    {2, "\\t"  }, /*   9 HTAB */
1147     {2, "\\n"  }, /*  10 NL   */    {2, "\\v"  }, /*  11 VTAB */
1148     {2, "\\f"  }, /*  12 FF   */    {2, "\\r"  }, /*  13 CR   */
1149     {4, "\\x0E"}, /*  14      */    {4, "\\x0F"}, /*  15      */
1150     {4, "\\x10"}, /*  16      */    {4, "\\x11"}, /*  17      */
1151     {4, "\\x12"}, /*  18      */    {4, "\\x13"}, /*  19      */
1152     {4, "\\x14"}, /*  20      */    {4, "\\x15"}, /*  21      */
1153     {4, "\\x16"}, /*  22      */    {4, "\\x17"}, /*  23      */
1154     {4, "\\x18"}, /*  24      */    {4, "\\x19"}, /*  25      */
1155     {4, "\\x1A"}, /*  26      */    {4, "\\x1B"}, /*  27      */
1156     {4, "\\x1C"}, /*  28      */    {4, "\\x1D"}, /*  29      */
1157     {4, "\\x1E"}, /*  30      */    {4, "\\x1F"}, /*  31      */
1158     {1, " "    }, /*  32      */    {1, "!"    }, /*  33 !    */
1159     {2, "\\\"" }, /*  34 "    */    {1, "#"    }, /*  35 #    */
1160     {1, "$"    }, /*  36 $    */    {1, "%"    }, /*  37 %    */
1161     {1, "&"    }, /*  38 &    */    {2, "\\'"  }, /*  39 '    */
1162     {1, "("    }, /*  40 (    */    {1, ")"    }, /*  41 )    */
1163     {1, "*"    }, /*  42 *    */    {1, "+"    }, /*  43 +    */
1164     {1, ","    }, /*  44 ,    */    {1, "-"    }, /*  45 -    */
1165     {1, "."    }, /*  46 .    */    {1, "/"    }, /*  47 /    */
1166     {1, "0"    }, /*  48 0    */    {1, "1"    }, /*  49 1    */
1167     {1, "2"    }, /*  50 2    */    {1, "3"    }, /*  51 3    */
1168     {1, "4"    }, /*  52 4    */    {1, "5"    }, /*  53 5    */
1169     {1, "6"    }, /*  54 6    */    {1, "7"    }, /*  55 7    */
1170     {1, "8"    }, /*  56 8    */    {1, "9"    }, /*  57 9    */
1171     {1, ":"    }, /*  58 :    */    {1, ";"    }, /*  59 ;    */
1172     {1, "<"    }, /*  60 <    */    {1, "="    }, /*  61 =    */
1173     {1, ">"    }, /*  62 >    */    {2, "\\?"  }, /*  63 ?    */
1174     {1, "@"    }, /*  64 @    */    {1, "A"    }, /*  65 A    */
1175     {1, "B"    }, /*  66 B    */    {1, "C"    }, /*  67 C    */
1176     {1, "D"    }, /*  68 D    */    {1, "E"    }, /*  69 E    */
1177     {1, "F"    }, /*  70 F    */    {1, "G"    }, /*  71 G    */
1178     {1, "H"    }, /*  72 H    */    {1, "I"    }, /*  73 I    */
1179     {1, "J"    }, /*  74 J    */    {1, "K"    }, /*  75 K    */
1180     {1, "L"    }, /*  76 L    */    {1, "M"    }, /*  77 M    */
1181     {1, "N"    }, /*  78 N    */    {1, "O"    }, /*  79 O    */
1182     {1, "P"    }, /*  80 P    */    {1, "Q"    }, /*  81 Q    */
1183     {1, "R"    }, /*  82 R    */    {1, "S"    }, /*  83 S    */
1184     {1, "T"    }, /*  84 T    */    {1, "U"    }, /*  85 U    */
1185     {1, "V"    }, /*  86 V    */    {1, "W"    }, /*  87 W    */
1186     {1, "X"    }, /*  88 X    */    {1, "Y"    }, /*  89 Y    */
1187     {1, "Z"    }, /*  90 Z    */    {1, "["    }, /*  91 [    */
1188     {2, "\\\\" }, /*  92 \    */    {1, "]"    }, /*  93 ]    */
1189     {1, "^"    }, /*  94 ^    */    {1, "_"    }, /*  95 _    */
1190     {1, "`"    }, /*  96 `    */    {1, "a"    }, /*  97 a    */
1191     {1, "b"    }, /*  98 b    */    {1, "c"    }, /*  99 c    */
1192     {1, "d"    }, /* 100 d    */    {1, "e"    }, /* 101 e    */
1193     {1, "f"    }, /* 102 f    */    {1, "g"    }, /* 103 g    */
1194     {1, "h"    }, /* 104 h    */    {1, "i"    }, /* 105 i    */
1195     {1, "j"    }, /* 106 j    */    {1, "k"    }, /* 107 k    */
1196     {1, "l"    }, /* 108 l    */    {1, "m"    }, /* 109 m    */
1197     {1, "n"    }, /* 110 n    */    {1, "o"    }, /* 111 o    */
1198     {1, "p"    }, /* 112 p    */    {1, "q"    }, /* 113 q    */
1199     {1, "r"    }, /* 114 r    */    {1, "s"    }, /* 115 s    */
1200     {1, "t"    }, /* 116 t    */    {1, "u"    }, /* 117 u    */
1201     {1, "v"    }, /* 118 v    */    {1, "w"    }, /* 119 w    */
1202     {1, "x"    }, /* 120 x    */    {1, "y"    }, /* 121 y    */
1203     {1, "z"    }, /* 122 z    */    {1, "{"    }, /* 123 {    */
1204     {1, "|"    }, /* 124 |    */    {1, "}"    }, /* 125 }    */
1205     {1, "~"    }, /* 126 ~    */    {4, "\\x7F"}, /* 127      */
1206     {4, "\\x80"}, /* 128      */    {4, "\\x81"}, /* 129      */
1207     {4, "\\x82"}, /* 130      */    {4, "\\x83"}, /* 131      */
1208     {4, "\\x84"}, /* 132      */    {4, "\\x85"}, /* 133      */
1209     {4, "\\x86"}, /* 134      */    {4, "\\x87"}, /* 135      */
1210     {4, "\\x88"}, /* 136      */    {4, "\\x89"}, /* 137      */
1211     {4, "\\x8A"}, /* 138      */    {4, "\\x8B"}, /* 139      */
1212     {4, "\\x8C"}, /* 140      */    {4, "\\x8D"}, /* 141      */
1213     {4, "\\x8E"}, /* 142      */    {4, "\\x8F"}, /* 143      */
1214     {4, "\\x90"}, /* 144      */    {4, "\\x91"}, /* 145      */
1215     {4, "\\x92"}, /* 146      */    {4, "\\x93"}, /* 147      */
1216     {4, "\\x94"}, /* 148      */    {4, "\\x95"}, /* 149      */
1217     {4, "\\x96"}, /* 150      */    {4, "\\x97"}, /* 151      */
1218     {4, "\\x98"}, /* 152      */    {4, "\\x99"}, /* 153      */
1219     {4, "\\x9A"}, /* 154      */    {4, "\\x9B"}, /* 155      */
1220     {4, "\\x9C"}, /* 156      */    {4, "\\x9D"}, /* 157      */
1221     {4, "\\x9E"}, /* 158      */    {4, "\\x9F"}, /* 159      */
1222     {4, "\\xA0"}, /* 160      */    {4, "\\xA1"}, /* 161      */
1223     {4, "\\xA2"}, /* 162      */    {4, "\\xA3"}, /* 163      */
1224     {4, "\\xA4"}, /* 164      */    {4, "\\xA5"}, /* 165      */
1225     {4, "\\xA6"}, /* 166      */    {4, "\\xA7"}, /* 167      */
1226     {4, "\\xA8"}, /* 168      */    {4, "\\xA9"}, /* 169      */
1227     {4, "\\xAA"}, /* 170      */    {4, "\\xAB"}, /* 171      */
1228     {4, "\\xAC"}, /* 172      */    {4, "\\xAD"}, /* 173      */
1229     {4, "\\xAE"}, /* 174      */    {4, "\\xAF"}, /* 175      */
1230     {4, "\\xB0"}, /* 176      */    {4, "\\xB1"}, /* 177      */
1231     {4, "\\xB2"}, /* 178      */    {4, "\\xB3"}, /* 179      */
1232     {4, "\\xB4"}, /* 180      */    {4, "\\xB5"}, /* 181      */
1233     {4, "\\xB6"}, /* 182      */    {4, "\\xB7"}, /* 183      */
1234     {4, "\\xB8"}, /* 184      */    {4, "\\xB9"}, /* 185      */
1235     {4, "\\xBA"}, /* 186      */    {4, "\\xBB"}, /* 187      */
1236     {4, "\\xBC"}, /* 188      */    {4, "\\xBD"}, /* 189      */
1237     {4, "\\xBE"}, /* 190      */    {4, "\\xBF"}, /* 191      */
1238     {4, "\\xC0"}, /* 192      */    {4, "\\xC1"}, /* 193      */
1239     {4, "\\xC2"}, /* 194      */    {4, "\\xC3"}, /* 195      */
1240     {4, "\\xC4"}, /* 196      */    {4, "\\xC5"}, /* 197      */
1241     {4, "\\xC6"}, /* 198      */    {4, "\\xC7"}, /* 199      */
1242     {4, "\\xC8"}, /* 200      */    {4, "\\xC9"}, /* 201      */
1243     {4, "\\xCA"}, /* 202      */    {4, "\\xCB"}, /* 203      */
1244     {4, "\\xCC"}, /* 204      */    {4, "\\xCD"}, /* 205      */
1245     {4, "\\xCE"}, /* 206      */    {4, "\\xCF"}, /* 207      */
1246     {4, "\\xD0"}, /* 208      */    {4, "\\xD1"}, /* 209      */
1247     {4, "\\xD2"}, /* 210      */    {4, "\\xD3"}, /* 211      */
1248     {4, "\\xD4"}, /* 212      */    {4, "\\xD5"}, /* 213      */
1249     {4, "\\xD6"}, /* 214      */    {4, "\\xD7"}, /* 215      */
1250     {4, "\\xD8"}, /* 216      */    {4, "\\xD9"}, /* 217      */
1251     {4, "\\xDA"}, /* 218      */    {4, "\\xDB"}, /* 219      */
1252     {4, "\\xDC"}, /* 220      */    {4, "\\xDD"}, /* 221      */
1253     {4, "\\xDE"}, /* 222      */    {4, "\\xDF"}, /* 223      */
1254     {4, "\\xE0"}, /* 224      */    {4, "\\xE1"}, /* 225      */
1255     {4, "\\xE2"}, /* 226      */    {4, "\\xE3"}, /* 227      */
1256     {4, "\\xE4"}, /* 228      */    {4, "\\xE5"}, /* 229      */
1257     {4, "\\xE6"}, /* 230      */    {4, "\\xE7"}, /* 231      */
1258     {4, "\\xE8"}, /* 232      */    {4, "\\xE9"}, /* 233      */
1259     {4, "\\xEA"}, /* 234      */    {4, "\\xEB"}, /* 235      */
1260     {4, "\\xEC"}, /* 236      */    {4, "\\xED"}, /* 237      */
1261     {4, "\\xEE"}, /* 238      */    {4, "\\xEF"}, /* 239      */
1262     {4, "\\xF0"}, /* 240      */    {4, "\\xF1"}, /* 241      */
1263     {4, "\\xF2"}, /* 242      */    {4, "\\xF3"}, /* 243      */
1264     {4, "\\xF4"}, /* 244      */    {4, "\\xF5"}, /* 245      */
1265     {4, "\\xF6"}, /* 246      */    {4, "\\xF7"}, /* 247      */
1266     {4, "\\xF8"}, /* 248      */    {4, "\\xF9"}, /* 249      */
1267     {4, "\\xFA"}, /* 250      */    {4, "\\xFB"}, /* 251      */
1268     {4, "\\xFC"}, /* 252      */    {4, "\\xFD"}, /* 253      */
1269     {4, "\\xFE"}, /* 254      */    {4, "\\xFF"}, /* 255      */
1270 };
1271 
1272 /* From nss/cmd/certutil/keystuff.c */
1273 static const unsigned char P[] = { 0,
1274        0x98, 0xef, 0x3a, 0xae, 0x70, 0x98, 0x9b, 0x44,
1275        0xdb, 0x35, 0x86, 0xc1, 0xb6, 0xc2, 0x47, 0x7c,
1276        0xb4, 0xff, 0x99, 0xe8, 0xae, 0x44, 0xf2, 0xeb,
1277        0xc3, 0xbe, 0x23, 0x0f, 0x65, 0xd0, 0x4c, 0x04,
1278        0x82, 0x90, 0xa7, 0x9d, 0x4a, 0xc8, 0x93, 0x7f,
1279        0x41, 0xdf, 0xf8, 0x80, 0x6b, 0x0b, 0x68, 0x7f,
1280        0xaf, 0xe4, 0xa8, 0xb5, 0xb2, 0x99, 0xc3, 0x69,
1281        0xfb, 0x3f, 0xe7, 0x1b, 0xd0, 0x0f, 0xa9, 0x7a,
1282        0x4a, 0x04, 0xbf, 0x50, 0x9e, 0x22, 0x33, 0xb8,
1283        0x89, 0x53, 0x24, 0x10, 0xf9, 0x68, 0x77, 0xad,
1284        0xaf, 0x10, 0x68, 0xb8, 0xd3, 0x68, 0x5d, 0xa3,
1285        0xc3, 0xeb, 0x72, 0x3b, 0xa0, 0x0b, 0x73, 0x65,
1286        0xc5, 0xd1, 0xfa, 0x8c, 0xc0, 0x7d, 0xaa, 0x52,
1287        0x29, 0x34, 0x44, 0x01, 0xbf, 0x12, 0x25, 0xfe,
1288        0x18, 0x0a, 0xc8, 0x3f, 0xc1, 0x60, 0x48, 0xdb,
1289        0xad, 0x93, 0xb6, 0x61, 0x67, 0xd7, 0xa8, 0x2d };
1290 static const unsigned char Q[] = { 0,
1291        0xb5, 0xb0, 0x84, 0x8b, 0x44, 0x29, 0xf6, 0x33,
1292        0x59, 0xa1, 0x3c, 0xbe, 0xd2, 0x7f, 0x35, 0xa1,
1293        0x76, 0x27, 0x03, 0x81                         };
1294 static const unsigned char G[] = {
1295        0x04, 0x0e, 0x83, 0x69, 0xf1, 0xcd, 0x7d, 0xe5,
1296        0x0c, 0x78, 0x93, 0xd6, 0x49, 0x6f, 0x00, 0x04,
1297        0x4e, 0x0e, 0x6c, 0x37, 0xaa, 0x38, 0x22, 0x47,
1298        0xd2, 0x58, 0xec, 0x83, 0x12, 0x95, 0xf9, 0x9c,
1299        0xf1, 0xf4, 0x27, 0xff, 0xd7, 0x99, 0x57, 0x35,
1300        0xc6, 0x64, 0x4c, 0xc0, 0x47, 0x12, 0x31, 0x50,
1301        0x82, 0x3c, 0x2a, 0x07, 0x03, 0x01, 0xef, 0x30,
1302        0x09, 0x89, 0x82, 0x41, 0x76, 0x71, 0xda, 0x9e,
1303        0x57, 0x8b, 0x76, 0x38, 0x37, 0x5f, 0xa5, 0xcd,
1304        0x32, 0x84, 0x45, 0x8d, 0x4c, 0x17, 0x54, 0x2b,
1305        0x5d, 0xc2, 0x6b, 0xba, 0x3e, 0xa0, 0x7b, 0x95,
1306        0xd7, 0x00, 0x42, 0xf7, 0x08, 0xb8, 0x83, 0x87,
1307        0x60, 0xe1, 0xe5, 0xf4, 0x1a, 0x54, 0xc2, 0x20,
1308        0xda, 0x38, 0x3a, 0xd1, 0xb6, 0x10, 0xf4, 0xcb,
1309        0x35, 0xda, 0x97, 0x92, 0x87, 0xd6, 0xa5, 0x37,
1310        0x62, 0xb4, 0x93, 0x4a, 0x15, 0x21, 0xa5, 0x10 };
1311 
1312 static const SECKEYPQGParams default_pqg_params = {
1313     NULL,
1314     { 0, (unsigned char *)P, sizeof(P) },
1315     { 0, (unsigned char *)Q, sizeof(Q) },
1316     { 0, (unsigned char *)G, sizeof(G) }
1317 };
1318 
1319 /*
1320  * Returns the number of bytes needed to escape an ascii string.
1321  */
1322 static size_t
ascii_encoded_strnlen(const char * str,size_t len)1323 ascii_encoded_strnlen(const char *str, size_t len)
1324 {
1325     size_t result;
1326     const unsigned char *s;     /* must be unsigned for table indexing to work */
1327 
1328     for (s = (unsigned char *)str, result = 0; len; s++, len--) {
1329         result += ascii_encoding_table[*s].len;
1330     }
1331     return result;
1332 }
1333 
1334 /* ========================================================================== */
1335 static char time_format[] = "%a %b %d %H:%M:%S %Y UTC";
1336 static char hex_chars[] = "0123456789abcdef";
1337 static PyObject *empty_tuple = NULL;
1338 static PyObject *py_empty_string = NULL;
1339 static PyObject *sec_oid_name_to_value = NULL;
1340 static PyObject *sec_oid_value_to_name = NULL;
1341 static PyObject *ckm_name_to_value = NULL;
1342 static PyObject *ckm_value_to_name = NULL;
1343 static PyObject *cka_name_to_value = NULL;
1344 static PyObject *cka_value_to_name = NULL;
1345 static PyObject *general_name_name_to_value = NULL;
1346 static PyObject *general_name_value_to_name = NULL;
1347 static PyObject *crl_reason_name_to_value = NULL;
1348 static PyObject *crl_reason_value_to_name = NULL;
1349 static PyObject *pkcs12_cipher_name_to_value = NULL;
1350 static PyObject *pkcs12_cipher_value_to_name = NULL;
1351 
1352 static PyTypeObject PK11SymKeyType;
1353 static PyTypeObject PK11ContextType;
1354 static PyTypeObject SecItemType;
1355 static PyTypeObject AVAType;
1356 static PyTypeObject RDNType;
1357 static PyTypeObject DNType;
1358 static PyTypeObject CertVerifyLogType;
1359 
1360 /* === Forward Declarations */
1361 
1362 static PyTypeObject CertDBType;
1363 static PyTypeObject CertificateType;
1364 static PyTypeObject PK11SlotType;
1365 
1366 /* === Prototypes === */
1367 
1368 static PyObject *
1369 obj_to_hex(PyObject *obj, int octets_per_line, char *separator);
1370 
1371 static PyObject *
1372 raw_data_to_hex(unsigned char *data, int data_len, int octets_per_line, char *separator);
1373 
1374 static SECStatus
1375 sec_strip_tag_and_length(SECItem *item);
1376 
1377 static PyObject *
1378 der_context_specific_secitem_to_pystr(SECItem *item);
1379 
1380 static PyObject *
1381 secitem_to_pystr_hex(SECItem *item);
1382 
1383 static PyObject *
1384 der_any_secitem_to_pystr(SECItem *item);
1385 
1386 static PyObject *
1387 der_set_or_str_secitem_to_pylist_of_pystr(SECItem *item);
1388 
1389 static PyObject *
1390 boolean_secitem_to_pystr(SECItem *item);
1391 
1392 static PyObject *
1393 der_boolean_secitem_to_pystr(SECItem *item);
1394 
1395 static PyObject *
1396 integer_secitem_to_pylong(SECItem *item);
1397 
1398 static PyObject *
1399 integer_secitem_to_pystr(SECItem *item);
1400 
1401 static PyObject *
1402 der_integer_secitem_to_pystr(SECItem *item);
1403 
1404 static bool
1405 is_oid_string(const char *oid_string);
1406 
1407 static SECOidTag
1408 ava_name_to_oid_tag(const char *name);
1409 
1410 static PyObject *
1411 oid_secitem_to_pystr_desc(SECItem *oid);
1412 
1413 static PyObject *
1414 oid_secitem_to_pyint_tag(SECItem *oid);
1415 
1416 static PyObject *
1417 oid_secitem_to_pystr_dotted_decimal(SECItem *oid);
1418 
1419 static PyObject *
1420 der_oid_secitem_to_pystr_desc(SECItem *item);
1421 
1422 static PyObject *
1423 der_utc_time_secitem_to_pystr(SECItem *item);
1424 
1425 static PyObject *
1426 der_generalized_time_secitem_to_pystr(SECItem *item);
1427 
1428 static PRTime
1429 time_choice_secitem_to_prtime(SECItem *item);
1430 
1431 static PyObject *
1432 time_choice_secitem_to_pystr(SECItem *item);
1433 
1434 static PyObject *
1435 der_octet_secitem_to_pystr(SECItem *item, int octets_per_line, char *separator);
1436 
1437 static PyObject *
1438 ascii_string_secitem_to_escaped_ascii_pystr(SECItem *item);
1439 
1440 static PyObject *
1441 der_ascii_string_secitem_to_escaped_ascii_pystr(SECItem *item);
1442 
1443 static PyObject *
1444 der_utf8_string_secitem_to_pyunicode(SECItem *item);
1445 
1446 static PyObject *
1447 der_bmp_string_secitem_to_pyunicode(SECItem *item);
1448 
1449 static PyObject *
1450 der_universal_string_secitem_to_pyunicode(SECItem *item);
1451 
1452 static PyObject *
1453 der_bit_string_secitem_to_pystr(SECItem *item);
1454 
1455 static PyObject *
1456 der_universal_secitem_to_pystr(SECItem *item);
1457 
1458 static PyObject *
1459 ip_addr_secitem_to_pystr(SECItem *item);
1460 
1461 static PyObject *
1462 CERTGeneralName_to_pystr_with_label(CERTGeneralName *general_name);
1463 
1464 static PyObject *
1465 CERTGeneralName_to_pystr(CERTGeneralName *general_name);
1466 
1467 static PyObject *
1468 cert_oid_tag_name(PyObject *self, PyObject *args);
1469 
1470 static PyObject *
1471 cert_trust_flags(unsigned int flags, RepresentationKind repr_kind);
1472 
1473 static int
1474 SecItem_init_from_data(SecItem *self, const void *data, Py_ssize_t len,
1475                        SECItemType type, SECItemKind kind);
1476 
1477 static PyObject *
1478 SecItem_new_from_SECItem(const SECItem *item, SECItemKind kind);
1479 
1480 static PyObject *
1481 SecItem_new_alloc(size_t len, SECItemType type, SECItemKind kind);
1482 
1483 static PyObject *
1484 pk11_md5_digest(PyObject *self, PyObject *args);
1485 
1486 static PyObject *
1487 pk11_sha1_digest(PyObject *self, PyObject *args);
1488 
1489 static PyObject *
1490 pk11_sha256_digest(PyObject *self, PyObject *args);
1491 
1492 static PyObject *
1493 pk11_sha512_digest(PyObject *self, PyObject *args);
1494 
1495 static PyObject *
1496 PyPK11Context_new_from_PK11Context(PK11Context *pk11_context);
1497 
1498 static PyObject *
1499 PyPK11SymKey_new_from_PK11SymKey(PK11SymKey *pk11_sym_key);
1500 
1501 static PyObject *
1502 key_mechanism_type_to_pystr(CK_MECHANISM_TYPE mechanism);
1503 
1504 static PyObject *
1505 pk11_attribute_type_to_pystr(CK_ATTRIBUTE_TYPE type);
1506 
1507 static PyObject *
1508 SignedCRL_new_from_CERTSignedCRL(CERTSignedCrl *signed_crl);
1509 
1510 static PyObject *
1511 AVA_repr(AVA *self);
1512 
1513 static bool
1514 CERTRDN_has_tag(CERTRDN *rdn, int tag);
1515 
1516 static PyObject *
1517 CERTAVA_value_to_pystr(CERTAVA *ava);
1518 
1519 static Py_ssize_t
1520 CERTRDN_ava_count(CERTRDN *rdn);
1521 
1522 static Py_ssize_t
1523 DN_length(DN *self);
1524 
1525 static PyObject *
1526 DN_item(DN *self, register Py_ssize_t i);
1527 
1528 static PyObject *
1529 general_name_type_to_pystr(CERTGeneralNameType type);
1530 
1531 static PyObject *
1532 CERTGeneralName_type_string_to_pystr(CERTGeneralName *general_name);
1533 
1534 static PyObject *
1535 CRLDistributionPt_general_names_tuple(CRLDistributionPt *self, RepresentationKind repr_kind);
1536 
1537 PyObject *
1538 GeneralName_new_from_CERTGeneralName(CERTGeneralName *name);
1539 
1540 static Py_ssize_t
1541 AuthKeyID_general_names_count(AuthKeyID *self);
1542 
1543 static PyObject *
1544 AuthKeyID_general_names_tuple(AuthKeyID *self, RepresentationKind repr_kind);
1545 
1546 static int
1547 set_thread_local(const char *name, PyObject *obj);
1548 
1549 static PyObject *
1550 get_thread_local(const char *name);
1551 
1552 static int
1553 del_thread_local(const char *name);
1554 
1555 static PyObject *
1556 SECItem_to_hex(SECItem *item, int octets_per_line, char *separator);
1557 
1558 static PyObject *
1559 SECItem_der_to_hex(SECItem *item, int octets_per_line, char *separator);
1560 
1561 static PyObject *
1562 cert_x509_key_usage(PyObject *self, PyObject *args, PyObject *kwds);
1563 
1564 static PyObject *
1565 cert_x509_cert_type(PyObject *self, PyObject *args, PyObject *kwds);
1566 
1567 PyObject *
1568 CRLDistributionPts_new_from_SECItem(SECItem *item);
1569 
1570 PyObject *
1571 AuthorityInfoAccesses_new_from_SECItem(SECItem *item);
1572 
1573 PyObject *
1574 AuthKeyID_new_from_SECItem(SECItem *item);
1575 
1576 static PyObject *
1577 cert_x509_ext_key_usage(PyObject *self, PyObject *args, PyObject *kwds);
1578 
1579 PyObject *
1580 BasicConstraints_new_from_SECItem(SECItem *item);
1581 
1582 static PyObject *
1583 cert_x509_alt_name(PyObject *self, PyObject *args, PyObject *kwds);
1584 
1585 PyObject *
1586 DN_new_from_CERTName(CERTName *name);
1587 
1588 PyObject *
1589 AlgorithmID_new_from_SECAlgorithmID(SECAlgorithmID *id);
1590 
1591 static PyObject *
1592 Certificate_new_from_signed_der_secitem(SECItem *der);
1593 
1594 static PyObject *
1595 Certificate_get_subject(Certificate *self, void *closure);
1596 
1597 static PyObject *
1598 Certificate_get_issuer(Certificate *self, void *closure);
1599 
1600 static PyObject *
1601 Certificate_new_from_CERTCertificate(CERTCertificate *cert, bool add_reference);
1602 
1603 static PyObject *
1604 fingerprint_format_lines(SECItem *item, int level);
1605 
1606 static PyObject *
1607 PKCS12Decoder_item(PKCS12Decoder *self, register Py_ssize_t i);
1608 
1609 PyObject *
1610 KEYPQGParams_init_from_SECKEYPQGParams(KEYPQGParams *self, const SECKEYPQGParams *params);
1611 
1612 static PyObject *
1613 CertVerifyLog_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
1614 
1615 static Py_ssize_t
1616 CertVerifyLog_length(CertVerifyLog *self);
1617 
1618 static PyObject *
1619 CertVerifyLog_item(CertVerifyLog *self, register Py_ssize_t i);
1620 
1621 static PyObject *
1622 CertAttribute_new_from_CERTAttribute(CERTAttribute *attr);
1623 
1624 PyObject *
1625 CertificateExtension_new_from_CERTCertExtension(CERTCertExtension *extension);
1626 
1627 static PyObject *
1628 CertificateExtension_get_name(CertificateExtension *self, void *closure);
1629 
1630 static PyObject *
1631 CertificateExtension_get_oid_tag(CertificateExtension *self, void *closure);
1632 
1633 static Py_ssize_t
1634 CERTCertExtension_count(CERTCertExtension **extensions);
1635 
1636 static PyObject *
1637 CERTCertExtension_tuple(CERTCertExtension **extensions, RepresentationKind repr_kind);
1638 
1639 static SECStatus
1640 CERTCertExtensions_from_CERTAttribute(PRArenaPool *arena,
1641                                       CERTAttribute *attr, CERTCertExtension ***exts);
1642 
1643 static SECStatus
1644 My_CERT_GetCertificateRequestExtensions(CERTCertificateRequest *req, CERTCertExtension ***exts);
1645 
1646 static PyObject *
1647 timestamp_to_DateTime(time_t timestamp, bool utc);
1648 
1649 static PyObject *
1650 pk11_pk11_disabled_reason_str(PyObject *self, PyObject *args);
1651 
1652 /* ==================================== */
1653 
1654 typedef struct BitStringTableStr {
1655     int enum_value;
1656     const char *enum_name;
1657     const char *enum_description;
1658 } BitStringTable;
1659 
1660 #define BITSTRING_TBL_INIT(enum, description) \
1661     {enum, #enum, description}
1662 
1663 static BitStringTable CRLReasonDef[] = {
1664     BITSTRING_TBL_INIT(crlEntryReasonUnspecified,          _("Unspecified")           ), /* bit 0  */
1665     BITSTRING_TBL_INIT(crlEntryReasonKeyCompromise,        _("Key Compromise")        ), /* bit 1  */
1666     BITSTRING_TBL_INIT(crlEntryReasonCaCompromise,         _("CA Compromise")         ), /* bit 2  */
1667     BITSTRING_TBL_INIT(crlEntryReasonAffiliationChanged,   _("Affiliation Changed")   ), /* bit 3  */
1668     BITSTRING_TBL_INIT(crlEntryReasonSuperseded,           _("Superseded")            ), /* bit 4  */
1669     BITSTRING_TBL_INIT(crlEntryReasonCessationOfOperation, _("Cessation Of Operation")), /* bit 5  */
1670     BITSTRING_TBL_INIT(crlEntryReasoncertificatedHold,     _("Certificate On Hold")   ), /* bit 6  */
1671     BITSTRING_TBL_INIT(-1,                                 NULL                       ), /* bit 7  */
1672     BITSTRING_TBL_INIT(crlEntryReasonRemoveFromCRL,        _("Remove From CRL")       ), /* bit 8  */
1673     BITSTRING_TBL_INIT(crlEntryReasonPrivilegeWithdrawn,   _("Privilege Withdrawn")   ), /* bit 9  */
1674     BITSTRING_TBL_INIT(crlEntryReasonAaCompromise,         _("AA Compromise")         ), /* bit 10 */
1675 };
1676 
1677 static BitStringTable KeyUsageDef[] = {
1678     BITSTRING_TBL_INIT(KU_DIGITAL_SIGNATURE, _("Digital Signature")  ), /* bit 0 */
1679     BITSTRING_TBL_INIT(KU_NON_REPUDIATION,   _("Non-Repudiation")    ), /* bit 1 */
1680     BITSTRING_TBL_INIT(KU_KEY_ENCIPHERMENT,  _("Key Encipherment")   ), /* bit 2 */
1681     BITSTRING_TBL_INIT(KU_DATA_ENCIPHERMENT, _("Data Encipherment")  ), /* bit 3 */
1682     BITSTRING_TBL_INIT(KU_KEY_AGREEMENT,     _("Key Agreement")      ), /* bit 4 */
1683     BITSTRING_TBL_INIT(KU_KEY_CERT_SIGN,     _("Certificate Signing")), /* bit 5 */
1684     BITSTRING_TBL_INIT(KU_CRL_SIGN,          _("CRL Signing")        ), /* bit 6 */
1685     BITSTRING_TBL_INIT(KU_ENCIPHER_ONLY,     _("Encipher Only")      ), /* bit 7 */
1686 #ifdef KU_DECIPHER_ONLY
1687     BITSTRING_TBL_INIT(KU_DECIPHER_ONLY,     _("Decipher Only")      ), /* bit 8 */
1688 #endif
1689 };
1690 
1691 static BitStringTable CertTypeDef[] = {
1692     BITSTRING_TBL_INIT(NS_CERT_TYPE_SSL_CLIENT,        _("SSL Client")        ), /* bit 0 */
1693     BITSTRING_TBL_INIT(NS_CERT_TYPE_SSL_SERVER,        _("SSL Server")        ), /* bit 1 */
1694     BITSTRING_TBL_INIT(NS_CERT_TYPE_EMAIL,             _("Email")             ), /* bit 2 */
1695     BITSTRING_TBL_INIT(NS_CERT_TYPE_OBJECT_SIGNING,    _("Object Signing")    ), /* bit 3 */
1696     BITSTRING_TBL_INIT(NS_CERT_TYPE_RESERVED,          _("Reserved")          ), /* bit 4 */
1697     BITSTRING_TBL_INIT(NS_CERT_TYPE_SSL_CA,            _("SSL CA")            ), /* bit 5 */
1698     BITSTRING_TBL_INIT(NS_CERT_TYPE_EMAIL_CA,          _("Email CA")          ), /* bit 6 */
1699     BITSTRING_TBL_INIT(NS_CERT_TYPE_OBJECT_SIGNING_CA, _("Object Signing CA") ), /* bit 7 */
1700 };
1701 
1702 static PyObject *
timestamp_to_DateTime(time_t timestamp,bool utc)1703 timestamp_to_DateTime(time_t timestamp, bool utc)
1704 {
1705     double d_timestamp = timestamp;
1706     PyObject *py_datetime = NULL;
1707     char *method;
1708 
1709     method = utc ? "utcfromtimestamp" : "fromtimestamp";
1710     if ((py_datetime =
1711          PyObject_CallMethod((PyObject *)PyDateTimeAPI->DateTimeType,
1712                              method, "(d)", d_timestamp)) == NULL) {
1713             return NULL;
1714     }
1715 
1716     return py_datetime;
1717 }
1718 
1719 /*
1720  * Parse text as base64 data. base64 may optionally be wrapped in PEM
1721  * header/footer. der SECItem must be freed with
1722  * SECITEM_FreeItem(&der, PR_FALSE);
1723  */
1724 static SECStatus
base64_to_SECItem(SECItem * der,char * text,size_t text_len)1725 base64_to_SECItem(SECItem *der, char *text, size_t text_len)
1726 {
1727     char *p, *text_end, *tmp, *der_begin, *der_end;
1728 
1729     der->data = NULL;
1730     der->len = 0;
1731     der->type = siBuffer;
1732 
1733     p = text;
1734     text_end = text + text_len;
1735     /* check for headers and trailers and remove them */
1736     if ((tmp = PL_strnstr(p, "-----BEGIN", text_end-p)) != NULL) {
1737         p = tmp;
1738         tmp = PORT_Strchr(p, '\n');
1739         if (!tmp) {
1740             tmp = strchr(p, '\r'); /* maybe this is a MAC file */
1741         }
1742         if (!tmp) {
1743             PyErr_SetString(PyExc_ValueError, "no line ending after PEM BEGIN");
1744             return SECFailure;
1745         }
1746         p = der_begin = tmp + 1;
1747         tmp = PL_strnstr(p, "-----END", text_end-p);
1748         if (tmp != NULL) {
1749             der_end = tmp;
1750             *der_end = '\0';
1751         } else {
1752             PyErr_SetString(PyExc_ValueError, "no PEM END found");
1753             return SECFailure;
1754         }
1755     } else {
1756         der_begin = p;
1757         der_end = p + strlen(p);
1758     }
1759 
1760     /* Convert to binary */
1761     if (NSSBase64_DecodeBuffer(NULL, der, der_begin, der_end - der_begin) == NULL) {
1762         set_nspr_error("Could not base64 decode");
1763         return SECFailure;
1764     }
1765     return SECSuccess;
1766 }
1767 
1768 /*
1769  * Parse text as base64 data. base64 may optionally be wrapped in PEM
1770  * header/footer. Return python SecItem.
1771  */
1772 static PyObject *
base64_to_SecItem(char * text)1773 base64_to_SecItem(char *text)
1774 {
1775     PyObject *py_sec_item;
1776     SECItem der;
1777 
1778     if (base64_to_SECItem(&der, text, strlen(text)) != SECSuccess) {
1779         return NULL;
1780     }
1781 
1782     py_sec_item = SecItem_new_from_SECItem(&der, SECITEM_unknown);
1783     SECITEM_FreeItem(&der, PR_FALSE);
1784     return py_sec_item;
1785 }
1786 
1787 static PyObject *
SECItem_to_base64(SECItem * item,size_t chars_per_line,char * pem_type)1788 SECItem_to_base64(SECItem *item, size_t chars_per_line, char *pem_type)
1789 {
1790     char *base64 = NULL;
1791     PyObject *lines = NULL;
1792     PyObject *py_base64 = NULL;
1793     size_t base64_len = 0;
1794 
1795     if ((base64 = NSSBase64_EncodeItem(NULL, NULL, 0, item)) == NULL) {
1796         return set_nspr_error("unable to encode SECItem to base64");
1797     }
1798 
1799     if (pem_type && chars_per_line == 0) {
1800         chars_per_line = 64;
1801     }
1802 
1803     base64_len = strlen(base64);
1804     if (chars_per_line) {
1805         size_t n_lines, line_number, line_len;
1806         char *src, *src_end;
1807         PyObject *line = NULL;
1808 
1809         n_lines = ((base64_len + chars_per_line - 1) / chars_per_line);
1810 
1811         if (pem_type) {
1812             n_lines += 2;
1813         }
1814 
1815         if ((lines = PyList_New(n_lines)) == NULL) {
1816             goto fail;
1817         }
1818         line_number = 0;
1819 
1820         if (pem_type) {
1821             if ((line = PyUnicode_FromFormat("-----BEGIN %s-----",
1822                                              pem_type)) == NULL) {
1823                 goto fail;
1824             }
1825             PyList_SetItem(lines, line_number++, line);
1826         }
1827 
1828         src = base64;
1829         src_end = base64 + base64_len;
1830 
1831         while(src < src_end) {
1832             line_len = MIN(chars_per_line, src_end - src);
1833             if ((line = PyUnicode_FromStringAndSize(src, line_len)) == NULL) {
1834                 goto fail;
1835             }
1836             PyList_SetItem(lines, line_number++, line);
1837 
1838             src += line_len;
1839         }
1840 
1841         if (pem_type) {
1842             if ((line = PyUnicode_FromFormat("-----END %s-----",
1843                                              pem_type)) == NULL) {
1844                 goto fail;
1845             }
1846             PyList_SetItem(lines, line_number++, line);
1847         }
1848 
1849         PORT_Free(base64);
1850         return lines;
1851     } else {
1852         py_base64 = PyUnicode_FromStringAndSize(base64, base64_len);
1853         PORT_Free(base64);
1854         return py_base64;
1855 
1856     }
1857 
1858  fail:
1859     if (base64)
1860         PORT_Free(base64);
1861     Py_XDECREF(lines);
1862     Py_XDECREF(py_base64);
1863     return NULL;
1864 }
1865 
1866 static bool
pyobject_has_method(PyObject * obj,const char * method_name)1867 pyobject_has_method(PyObject* obj, const char *method_name)
1868 {
1869     PyObject *attr;
1870     int is_callable;
1871 
1872     if ((attr = PyObject_GetAttrString(obj, method_name)) == NULL) {
1873         return false;
1874     }
1875     is_callable = PyCallable_Check(attr);
1876     Py_DECREF(attr);
1877     return is_callable ? true : false;
1878 }
1879 
1880 /*
1881  * pyfile_open_filename
1882  *
1883  * :Parameters:
1884  *     py_filename : file name (PyObject)
1885  *         The pathname of the file to open
1886  *         otherwise check if the object has a read() method.
1887  *     mode: string that specifies the mode in which the file
1888  *         is opened, see io.open for details.
1889  * :Return:
1890  *     Returns a PyFile object if successful, NULL otherwise.
1891  *
1892  */
1893 
1894 static PyObject *
pyfile_open_filename(PyObject * py_filename,const char * mode)1895 pyfile_open_filename(PyObject *py_filename, const char *mode)
1896 {
1897     PyObject *io = NULL;
1898     PyObject *py_file = NULL;
1899 
1900     if ((io = PyImport_ImportModule("io")) == NULL) {
1901         return NULL;
1902     }
1903 
1904     if ((py_file = PyObject_CallMethod(io, "open", "Os", py_filename, mode)) == NULL) {
1905         Py_DECREF(io);
1906         return NULL;
1907     }
1908 
1909     Py_DECREF(io);
1910     return py_file;
1911 }
1912 
1913 /*
1914  * read_data_from_file(PyObject *file_arg)
1915  *
1916  * :Parameters:
1917  *     file_arg : file name or file object
1918  *         If string treat as file path to open and read,
1919  *         otherwise check if the object has a read() method.
1920  *     mode: string that specifies the mode in which the file
1921  *         is opened, see io.open for details.
1922  *
1923  * Read the contents of a file and return as a python object.
1924  * If file is a string then treat it as a file pathname by opening
1925  * and reading the contents of that file. If file is a file object
1926  * then read the contents from the file object.
1927  *
1928  * The returned python object should be either a PyBytes object if
1929  * opened in binary mode or a PyUnicode object if opened in text
1930  * mode. If the file_arg was an object with read method you won't know
1931  * a prori what the mode is, therefore it's best practice to
1932  * explicitly check the type of the returned object.
1933  */
1934 static PyObject *
read_data_from_file(PyObject * file_arg,const char * mode)1935 read_data_from_file(PyObject *file_arg, const char *mode)
1936 {
1937     PyObject *py_file=NULL;
1938     PyObject *py_file_contents=NULL;
1939     bool need_close = false;
1940 
1941     if (PyBaseString_Check(file_arg)) {
1942         if ((py_file = pyfile_open_filename(file_arg, mode)) == NULL) {
1943             return NULL;
1944         }
1945         need_close = true;
1946     } else if (pyobject_has_method(file_arg, "read")) {
1947         py_file = file_arg;
1948 	Py_INCREF(py_file);
1949     } else {
1950         PyErr_SetString(PyExc_TypeError, "Bad file, must be pathname or file like object with read() method");
1951         return NULL;
1952     }
1953 
1954     if ((py_file_contents = PyObject_CallMethod(py_file, "read", NULL)) == NULL) {
1955         if (need_close) {
1956             PyObject_CallMethod(py_file, "close", NULL);
1957         }
1958         Py_DECREF(py_file);
1959         return NULL;
1960     }
1961     if (need_close) {
1962         PyObject_CallMethod(py_file, "close", NULL);
1963     }
1964     Py_DECREF(py_file);
1965 
1966     return py_file_contents;
1967 }
1968 
1969 /******************************************************************************/
1970 
1971 typedef struct {
1972     SECItem item;
1973     Py_buffer py_buffer;
1974 } SECItem_param;
1975 
1976 static int
SECItemConvert(PyObject * obj,SECItem_param ** param)1977 SECItemConvert(PyObject *obj, SECItem_param **param)
1978 {
1979     SECItem_param *ip = NULL;
1980 
1981     *param = NULL;
1982 
1983     if (!obj) {
1984         return 0;
1985     }
1986 
1987     if (PySecItem_Check(obj)) {
1988         if ((ip = PyMem_MALLOC(sizeof(SECItem_param))) == NULL) {
1989             return 0;
1990         }
1991         ip->item = ((SecItem *)obj)->item;
1992         ip->py_buffer.obj = NULL;
1993         *param = ip;
1994         return 1;
1995     } else if (PyObject_CheckBuffer(obj)) {
1996         if ((ip = PyMem_MALLOC(sizeof(SECItem_param))) == NULL) {
1997             return 0;
1998         }
1999 
2000         if (PyObject_GetBuffer(obj, &ip->py_buffer, PyBUF_SIMPLE) != 0) {
2001             PyMem_Free(ip);
2002             return 0;
2003         }
2004 
2005         ip->item.data = ip->py_buffer.buf;
2006         ip->item.len = ip->py_buffer.len;
2007         ip->item.type = siBuffer;
2008         *param = ip;
2009         return 1;
2010     }
2011 
2012     PyErr_Format(PyExc_TypeError, "must be SecItem or buffer object");
2013     return 0;
2014 }
2015 
2016 static int
SECItemOrNoneConvert(PyObject * obj,SECItem_param ** param)2017 SECItemOrNoneConvert(PyObject *obj, SECItem_param **param)
2018 {
2019     SECItem_param *ip = NULL;
2020     *param = NULL;
2021 
2022     if (!obj) {
2023         return 1;
2024     }
2025 
2026     if (PySecItem_Check(obj)) {
2027         if ((ip = PyMem_MALLOC(sizeof(SECItem_param))) == NULL) {
2028             return 0;
2029         }
2030         ip->item = ((SecItem *)obj)->item;
2031         ip->py_buffer.obj = NULL;
2032         *param = ip;
2033         return 1;
2034     } else if (PyObject_CheckBuffer(obj)) {
2035         if ((ip = PyMem_MALLOC(sizeof(SECItem_param))) == NULL) {
2036             return 0;
2037         }
2038 
2039         if (PyObject_GetBuffer(obj, &ip->py_buffer, PyBUF_SIMPLE) != 0) {
2040             PyMem_Free(ip);
2041             return 0;
2042         }
2043 
2044         ip->item.data = ip->py_buffer.buf;
2045         ip->item.len = ip->py_buffer.len;
2046         ip->item.type = siBuffer;
2047         *param = ip;
2048         return 1;
2049     } else if (PyNone_Check(obj)) {
2050         *param = NULL;
2051         return 1;
2052     }
2053 
2054     PyErr_Format(PyExc_TypeError, "must be SecItem, buffer object or None");
2055     return 0;
2056 }
2057 
2058 static void
SECItem_param_release(SECItem_param * ip)2059 SECItem_param_release(SECItem_param *ip)
2060 {
2061     if (!ip) return;
2062 
2063     PyBuffer_Release(&ip->py_buffer);
2064     PyMem_Free(ip);
2065 }
2066 
2067 static int
SecItemOrNoneConvert(PyObject * obj,PyObject ** param)2068 SecItemOrNoneConvert(PyObject *obj, PyObject **param)
2069 {
2070     if (PySecItem_Check(obj)) {
2071         *param = obj;
2072         return 1;
2073     }
2074 
2075     if (PyNone_Check(obj)) {
2076         *param = NULL;
2077         return 1;
2078     }
2079 
2080     PyErr_Format(PyExc_TypeError, "must be %.50s or None, not %.50s",
2081                  SecItemType.tp_name, Py_TYPE(obj)->tp_name);
2082     return 0;
2083 }
2084 
2085 /******************************************************************************/
2086 
2087 
2088 static SECStatus
secport_ucs2_swap_bytes(SECItem * ucs2_item)2089 secport_ucs2_swap_bytes(SECItem *ucs2_item)
2090 {
2091     unsigned int i;
2092     unsigned char tmp;
2093 
2094     if ((ucs2_item == NULL) || (ucs2_item->len % 2)) {
2095         return SECFailure;
2096     }
2097 
2098     for (i = 0; i < ucs2_item->len; i += 2) {
2099         tmp = ucs2_item->data[i];
2100         ucs2_item->data[i] = ucs2_item->data[i+1];
2101         ucs2_item->data[i+1] = tmp;
2102     }
2103     return SECSuccess;
2104 }
2105 
2106 static PRBool
secport_ucs2_to_utf8(PRBool to_unicode,unsigned char * in_buf,unsigned int in_buf_len,unsigned char * out_buf,unsigned int max_out_buf_len,unsigned int * out_buf_len,PRBool swap_bytes)2107 secport_ucs2_to_utf8(PRBool to_unicode,
2108                      unsigned char *in_buf, unsigned int in_buf_len,
2109                      unsigned char *out_buf, unsigned int max_out_buf_len, unsigned int *out_buf_len,
2110                      PRBool swap_bytes)
2111 {
2112     SECItem src_item = {siBuffer, NULL, 0};
2113     SECItem *swapped_item = NULL;
2114     PRBool result;
2115 
2116     /* If converting Unicode to ASCII, swap bytes before conversion as neccessary. */
2117     if (!to_unicode && swap_bytes) {
2118         SECItem in_buf_item = {siBuffer, NULL, 0};
2119 
2120         in_buf_item.data = in_buf;
2121         in_buf_item.len = in_buf_len;
2122         swapped_item = SECITEM_DupItem(&in_buf_item);
2123 
2124         if (secport_ucs2_swap_bytes(swapped_item) != SECSuccess) {
2125             SECITEM_ZfreeItem(swapped_item, PR_TRUE);
2126             return PR_FALSE;
2127         }
2128 
2129         src_item = *swapped_item;
2130 
2131     } else {
2132         src_item.data = in_buf;
2133         src_item.len = in_buf_len;
2134     }
2135 
2136     /* Perform the conversion. */
2137     result = PORT_UCS2_UTF8Conversion(to_unicode, src_item.data, src_item.len,
2138                                       out_buf, max_out_buf_len, out_buf_len);
2139     if (swapped_item)
2140         SECITEM_ZfreeItem(swapped_item, PR_TRUE);
2141 
2142     return result;
2143 }
2144 
2145 /*
2146  * NSS WART
2147  * NSS encodes a bit string in a SECItem by setting the len field
2148  * to a bit count and stripping off the leading "unused" octet.
2149  */
2150 static int
der_bitstring_to_nss_bitstring(SECItem * dst,SECItem * src)2151 der_bitstring_to_nss_bitstring(SECItem *dst, SECItem *src) {
2152     unsigned long data_len;
2153     int src_len;
2154     unsigned char *src_data, octet, unused;
2155 
2156     if (!src || !dst) {
2157 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
2158         return SECFailure;
2159     }
2160 
2161     src_len = src->len;
2162     src_data = src->data;
2163 
2164     /* First octet is ASN1 type */
2165     if (src_len <= 0) goto bad_data;
2166     octet = *src_data++; src_len--;
2167 
2168     if ((octet & SEC_ASN1_TAGNUM_MASK) != SEC_ASN1_BIT_STRING)
2169         goto bad_data;
2170 
2171     /* Next octets are ASN1 length */
2172     if (src_len <= 0) goto bad_data;
2173     octet = *src_data++; src_len--;
2174 
2175     data_len = octet;
2176     if (data_len & 0x80) {
2177         int  len_count = data_len & 0x7f;
2178 
2179         if (len_count > src_len)
2180             goto bad_data;
2181 
2182         for (data_len = 0, octet = *src_data++, src_len--;
2183              len_count;
2184              len_count--,  octet = *src_data++, src_len--) {
2185             data_len = (data_len << 8) | octet;
2186         }
2187     }
2188 
2189     /* After ASN1 length comes one octet containing the unused bit count */
2190     if (src_len <= 0) goto bad_data;
2191     unused = *src_data++; src_len--;
2192 
2193     if (data_len <= 1) {
2194         goto bad_data;
2195     } else {
2196         data_len--;             /* account for unused octet */
2197         dst->len = (data_len << 3) - (unused & 0x07);
2198         dst->data = src_len > 0 ? src_data : NULL;
2199     }
2200 
2201     return SECSuccess;
2202 
2203  bad_data:
2204     PORT_SetError(SEC_ERROR_BAD_DATA);
2205     return SECFailure;
2206 }
2207 
2208 /*
2209  * Given a decoded bit string in a SECItem (where len is a bit count and
2210  * the high bit of data[0] is bit[0] of the bitstring) return a tuple of
2211  * every enabled bit in the bit string. The members of the tuple come from
2212  * a table of predined values for the bit string. The repr_kind
2213  * enumeration specifies what type of item should be put in the tuple, for
2214  * example the string name for the bit position, or the enumerated constant
2215  * representing that bit postion, or the bit posisiton.
2216  */
2217 static PyObject *
bitstr_table_to_tuple(SECItem * bitstr,BitStringTable * table,size_t table_len,RepresentationKind repr_kind)2218 bitstr_table_to_tuple(SECItem *bitstr, BitStringTable *table,
2219                       size_t table_len, RepresentationKind repr_kind)
2220 {
2221     PyObject *tuple = NULL;
2222     size_t bitstr_len, len, count, i, j;
2223     unsigned char *data, octet = 0, mask = 0x80;
2224 
2225     bitstr_len = bitstr->len;
2226     len = MIN(table_len, bitstr_len);
2227 
2228     /*
2229      * Get a count of how many bits are enabled.
2230      * Skip any undefined entries in the table.
2231      */
2232     count = 0;
2233     if (bitstr->data != NULL) {
2234         for (i = 0, data = bitstr->data; i < len; i++) {
2235             if ((i % 8) == 0) {
2236                 octet = *data++;
2237                 mask = 0x80;
2238             }
2239             if (octet & mask) {
2240                 if (table[i].enum_description) { /* only if defined in table */
2241                     count++;
2242                 }
2243             }
2244             mask >>= 1;
2245         }
2246     }
2247 
2248     if ((tuple = PyTuple_New(count)) == NULL) {
2249         return NULL;
2250     }
2251 
2252     if (count == 0) {
2253         return tuple;
2254     }
2255 
2256     /* Populate the tuple */
2257     for (i = j = 0, data = bitstr->data; i < len; i++) {
2258         if ((i % 8) == 0) {
2259             octet = *data++;
2260             mask = 0x80;
2261         }
2262         if (octet & mask) {
2263             if (table[i].enum_description) { /* only if defined in table */
2264                 switch(repr_kind) {
2265                 case AsEnum:
2266                     PyTuple_SetItem(tuple, j++, PyLong_FromLong(table[i].enum_value));
2267                     break;
2268                 case AsEnumName:
2269                     PyTuple_SetItem(tuple, j++, PyUnicode_FromString(table[i].enum_name));
2270                     break;
2271                 case AsEnumDescription:
2272                     PyTuple_SetItem(tuple, j++, PyUnicode_FromString(table[i].enum_description));
2273                     break;
2274                 case AsIndex:
2275                     PyTuple_SetItem(tuple, j++, PyLong_FromLong(i));
2276                     break;
2277                 default:
2278                     PyErr_Format(PyExc_ValueError, "Unsupported representation kind (%d)", repr_kind);
2279                     Py_DECREF(tuple);
2280                     return NULL;
2281                     break;
2282                 }
2283             }
2284         }
2285         mask >>= 1;
2286     }
2287 
2288     return tuple;
2289 }
2290 
2291 static PyObject *
crl_reason_bitstr_to_tuple(SECItem * bitstr,RepresentationKind repr_kind)2292 crl_reason_bitstr_to_tuple(SECItem *bitstr, RepresentationKind repr_kind)
2293 {
2294     size_t table_len;
2295 
2296     table_len = sizeof(CRLReasonDef) / sizeof(CRLReasonDef[0]);
2297     return bitstr_table_to_tuple(bitstr, CRLReasonDef, table_len, repr_kind);
2298 }
2299 
2300 static PyObject *
key_usage_bitstr_to_tuple(SECItem * bitstr,RepresentationKind repr_kind)2301 key_usage_bitstr_to_tuple(SECItem *bitstr, RepresentationKind repr_kind)
2302 {
2303     size_t table_len;
2304 
2305     table_len = sizeof(KeyUsageDef) / sizeof(KeyUsageDef[0]);
2306     return bitstr_table_to_tuple(bitstr, KeyUsageDef, table_len, repr_kind);
2307 }
2308 
2309 static PyObject *
cert_type_bitstr_to_tuple(SECItem * bitstr,RepresentationKind repr_kind)2310 cert_type_bitstr_to_tuple(SECItem *bitstr, RepresentationKind repr_kind)
2311 {
2312     size_t table_len;
2313 
2314     table_len = sizeof(CertTypeDef) / sizeof(CertTypeDef[0]);
2315     return bitstr_table_to_tuple(bitstr, CertTypeDef, table_len, repr_kind);
2316 }
2317 
2318 static PyObject *
decode_oid_sequence_to_tuple(SECItem * item,RepresentationKind repr_kind)2319 decode_oid_sequence_to_tuple(SECItem *item, RepresentationKind repr_kind)
2320 {
2321     int i, n_oids;
2322     PyObject *tuple;
2323     CERTOidSequence *os;
2324     SECItem **op;
2325     PyObject *py_oid;
2326 
2327     if (!item || !item->len || !item->data) {
2328         PyErr_SetString(PyExc_ValueError, "missing DER encoded OID data");
2329         return NULL;
2330     }
2331 
2332     if ((os = CERT_DecodeOidSequence(item)) == NULL) {
2333         return set_nspr_error("unable to decode OID sequence");
2334     }
2335 
2336     /* Get a count of how many OID's there were */
2337     for(op = os->oids, n_oids = 0; *op; op++, n_oids++);
2338 
2339     if ((tuple = PyTuple_New(n_oids)) == NULL) {
2340         CERT_DestroyOidSequence(os);
2341         return NULL;
2342     }
2343 
2344     /* Iterate over each OID and insert into tuple */
2345     for(op = os->oids, i = 0; *op; op++, i++) {
2346         switch(repr_kind) {
2347         case AsObject:
2348             if ((py_oid = SecItem_new_from_SECItem(*op, SECITEM_oid)) == NULL) {
2349                 Py_DECREF(tuple);
2350                 CERT_DestroyOidSequence(os);
2351                 return NULL;
2352             }
2353             break;
2354         case AsString:
2355             if ((py_oid = oid_secitem_to_pystr_desc(*op)) == NULL) {
2356                 Py_DECREF(tuple);
2357                 CERT_DestroyOidSequence(os);
2358                 return NULL;
2359             }
2360             break;
2361         case AsDottedDecimal:
2362             if ((py_oid = oid_secitem_to_pystr_dotted_decimal(*op)) == NULL) {
2363                 Py_DECREF(tuple);
2364                 CERT_DestroyOidSequence(os);
2365                 return NULL;
2366             }
2367             break;
2368         case AsEnum:
2369             if ((py_oid = oid_secitem_to_pyint_tag(*op)) == NULL) {
2370                 Py_DECREF(tuple);
2371                 CERT_DestroyOidSequence(os);
2372                 return NULL;
2373             }
2374             break;
2375         default:
2376             PyErr_Format(PyExc_ValueError, "Unsupported representation kind (%d)", repr_kind);
2377             Py_DECREF(tuple);
2378             CERT_DestroyOidSequence(os);
2379             return NULL;
2380         }
2381         PyTuple_SetItem(tuple, i, py_oid);
2382     }
2383     CERT_DestroyOidSequence(os);
2384 
2385     return tuple;
2386 }
2387 
2388 static Py_ssize_t
CERTCertExtension_count(CERTCertExtension ** extensions)2389 CERTCertExtension_count(CERTCertExtension **extensions)
2390 {
2391     Py_ssize_t count;
2392 
2393     if (extensions == NULL) return 0;
2394     for (count = 0; *extensions; extensions++, count++);
2395     return count;
2396 }
2397 
2398 static PyObject *
CERTCertExtension_tuple(CERTCertExtension ** extensions,RepresentationKind repr_kind)2399 CERTCertExtension_tuple(CERTCertExtension **extensions, RepresentationKind repr_kind)
2400 {
2401     Py_ssize_t n_extensions, i;
2402     PyObject *tuple=NULL, *py_ext=NULL, *py_obj=NULL;
2403     CERTCertExtension *ext;
2404 
2405     n_extensions = CERTCertExtension_count(extensions);
2406 
2407     if (n_extensions == 0) {
2408         Py_INCREF(empty_tuple);
2409         return empty_tuple;
2410     }
2411 
2412     if ((tuple = PyTuple_New(n_extensions)) == NULL) {
2413         return NULL;
2414     }
2415 
2416     for (i = 0; i < n_extensions; i++) {
2417         ext = extensions[i];
2418         if ((py_ext = CertificateExtension_new_from_CERTCertExtension(ext)) == NULL) {
2419             goto fail;
2420         }
2421 
2422         switch(repr_kind) {
2423         case AsObject:
2424             py_obj = py_ext;
2425             Py_INCREF(py_obj);
2426             break;
2427         case AsString:
2428             if ((py_obj = CertificateExtension_get_name((CertificateExtension *)py_ext, NULL)) == NULL) {
2429                 goto fail;
2430             }
2431             break;
2432         case AsEnum:
2433             if ((py_obj = CertificateExtension_get_oid_tag((CertificateExtension *)py_ext, NULL)) == NULL) {
2434                 goto fail;
2435             }
2436             break;
2437         default:
2438             PyErr_Format(PyExc_ValueError, "Unsupported representation kind (%d)", repr_kind);
2439             goto fail;
2440         }
2441         PyTuple_SetItem(tuple, i, py_obj);
2442         Py_CLEAR(py_ext);
2443     }
2444 
2445     return tuple;
2446 
2447  fail:
2448     Py_XDECREF(tuple);
2449     Py_XDECREF(py_ext);
2450     return NULL;
2451 }
2452 
2453 
2454 static PyObject *
PK11SlotList_to_tuple(PK11SlotList * list)2455 PK11SlotList_to_tuple(PK11SlotList *list)
2456 {
2457     Py_ssize_t len, i;
2458     PyObject *tuple = NULL;
2459     PyObject *py_slotinfo = NULL;
2460     PK11SlotListElement *le;
2461 
2462     /* Count number of elements in list, allocate tuple */
2463     for (le = list->head, len = 0; le; le = le->next) len++;
2464 
2465     if ((tuple = PyTuple_New(len)) == NULL) {
2466         return NULL;
2467     }
2468 
2469     for (le = list->head, i = 0; le; le = le->next, i++) {
2470         if ((py_slotinfo = PK11Slot_new_from_PK11SlotInfo(le->slot)) == NULL) {
2471             Py_DECREF(tuple);
2472             return NULL;
2473         }
2474         PyTuple_SetItem(tuple, i, py_slotinfo);
2475     }
2476 
2477     return tuple;
2478 }
2479 
2480 static PyObject *
CERTCertList_to_tuple(CERTCertList * cert_list,bool add_reference)2481 CERTCertList_to_tuple(CERTCertList *cert_list, bool add_reference)
2482 {
2483     Py_ssize_t n_certs = 0;
2484     Py_ssize_t i = 0;
2485     CERTCertListNode *node = NULL;
2486     PyObject *py_cert = NULL;
2487     PyObject *tuple = NULL;
2488 
2489     for (node = CERT_LIST_HEAD(cert_list), n_certs = 0;
2490          !CERT_LIST_END(node, cert_list);
2491          node = CERT_LIST_NEXT(node), n_certs++);
2492 
2493     if ((tuple = PyTuple_New(n_certs)) == NULL) {
2494         return NULL;
2495     }
2496 
2497     for (node = CERT_LIST_HEAD(cert_list), i = 0;
2498          !CERT_LIST_END(node, cert_list);
2499          node = CERT_LIST_NEXT(node), i++) {
2500         if ((py_cert = Certificate_new_from_CERTCertificate(node->cert, add_reference)) == NULL) {
2501             Py_DECREF(tuple);
2502             return NULL;
2503         }
2504         PyTuple_SetItem(tuple, i, py_cert);
2505     }
2506     return tuple;
2507 }
2508 
2509 /* NSS WART: CERT_CopyAVA is hidden, but we need it, copied here from secname.c */
2510 CERTAVA *
CERT_CopyAVA(PRArenaPool * arena,CERTAVA * from)2511 CERT_CopyAVA(PRArenaPool *arena, CERTAVA *from)
2512 {
2513     CERTAVA *ava;
2514     int rv;
2515 
2516     ava = (CERTAVA*) PORT_ArenaZAlloc(arena, sizeof(CERTAVA));
2517     if (ava) {
2518 	rv = SECITEM_CopyItem(arena, &ava->type, &from->type);
2519 	if (rv) goto loser;
2520 	rv = SECITEM_CopyItem(arena, &ava->value, &from->value);
2521 	if (rv) goto loser;
2522     }
2523     return ava;
2524 
2525   loser:
2526     return NULL;
2527 }
2528 
2529 static SECStatus
CERT_CopyGeneralName(PRArenaPool * arena,CERTGeneralName ** pdst,CERTGeneralName * src)2530 CERT_CopyGeneralName(PRArenaPool *arena, CERTGeneralName **pdst, CERTGeneralName *src)
2531 {
2532     SECStatus result = SECSuccess;
2533     void *mark = NULL;
2534     CERTGeneralName *dst;
2535 
2536     /*
2537      * NSS WART
2538      * There is no public API to create a CERTGeneralName, copy it, or free it.
2539      * You don't know what arena was used to create the general name.
2540      * GeneralNames are linked in a list, this makes it difficult for a
2541      * general name to exist independently, it would have been better if there
2542      * was a list container independent general names could be placed in,
2543      * then you wouldn't have to worry about the link fields in each independent name.
2544      *
2545      * The logic here is copied from cert_CopyOneGeneralName in certdb/genname.c
2546      */
2547 
2548     if (!arena) {
2549 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
2550         return SECFailure;
2551     }
2552 
2553     if (!src) {
2554 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
2555         return SECFailure;
2556     }
2557 
2558     mark = PORT_ArenaMark(arena);
2559 
2560     if ((dst = PORT_ArenaZNew(arena, CERTGeneralName)) == NULL) {
2561         result = SECFailure;
2562         goto exit;
2563     }
2564 
2565     dst->l.prev = dst->l.next = &dst->l;
2566     dst->type = src->type;
2567 
2568     switch (src->type) {
2569     case certDirectoryName:
2570 	if ((result = SECITEM_CopyItem(arena, &dst->derDirectoryName,
2571                                        &src->derDirectoryName)) != SECSuccess) {
2572             goto exit;
2573         }
2574         if ((result = CERT_CopyName(arena, &dst->name.directoryName,
2575                                     &src->name.directoryName)) != SECSuccess) {
2576             goto exit;
2577         }
2578 	break;
2579 
2580     case certOtherName:
2581 	if ((result = SECITEM_CopyItem(arena, &dst->name.OthName.name,
2582                                        &src->name.OthName.name)) != SECSuccess) {
2583             goto exit;
2584         }
2585         if ((result = SECITEM_CopyItem(arena, &dst->name.OthName.oid,
2586                                        &src->name.OthName.oid)) != SECSuccess) {
2587             goto exit;
2588         }
2589 	break;
2590 
2591     default:
2592 	if ((result = SECITEM_CopyItem(arena, &dst->name.other,
2593                                        &src->name.other)) != SECSuccess) {
2594             goto exit;
2595         }
2596 	break;
2597 
2598     }
2599 
2600 
2601  exit:
2602     if (result == SECSuccess) {
2603         *pdst = dst;
2604         PORT_ArenaUnmark(arena, mark);
2605     } else {
2606         *pdst = NULL;
2607         PORT_ArenaRelease(arena, mark);
2608     }
2609     return result;
2610 }
2611 
2612 static Py_ssize_t
CERTGeneralName_list_count(CERTGeneralName * head)2613 CERTGeneralName_list_count(CERTGeneralName *head)
2614 {
2615     CERTGeneralName *cur;
2616     Py_ssize_t count;
2617 
2618     count = 0;
2619     if (!head) {
2620         return count;
2621     }
2622 
2623     cur = head;
2624     do {
2625         count++;
2626         cur = CERT_GetNextGeneralName(cur);
2627     } while (cur != head);
2628 
2629     return count;
2630 }
2631 
2632 static PyObject *
CERTGeneralName_list_to_tuple(CERTGeneralName * head,RepresentationKind repr_kind)2633 CERTGeneralName_list_to_tuple(CERTGeneralName *head, RepresentationKind repr_kind)
2634 {
2635     CERTGeneralName *cur;
2636     Py_ssize_t n_names, i;
2637     PyObject *names;
2638 
2639     n_names = CERTGeneralName_list_count(head);
2640 
2641     if ((names = PyTuple_New(n_names)) == NULL) {
2642         return NULL;
2643     }
2644 
2645     if (n_names == 0) {
2646         return names;
2647     }
2648 
2649     i = 0;
2650     cur = head;
2651     do {
2652         PyObject *name;
2653 
2654         switch(repr_kind) {
2655         case AsObject:
2656             name = GeneralName_new_from_CERTGeneralName(cur);
2657             break;
2658         case AsString:
2659             name = CERTGeneralName_to_pystr(cur);
2660             break;
2661         case AsTypeString:
2662             name = CERTGeneralName_type_string_to_pystr(cur);
2663             break;
2664         case AsTypeEnum:
2665             name = PyLong_FromLong(cur->type);
2666             break;
2667         case AsLabeledString:
2668             name = CERTGeneralName_to_pystr_with_label(cur);
2669             break;
2670         default:
2671             PyErr_Format(PyExc_ValueError, "Unsupported representation kind (%d)", repr_kind);
2672             Py_DECREF(names);
2673             return NULL;
2674         }
2675         PyTuple_SetItem(names, i, name);
2676         cur = CERT_GetNextGeneralName(cur);
2677         i++;
2678     } while (cur != head);
2679 
2680 
2681     return names;
2682 }
2683 
2684 static SECStatus
CERT_CopyGeneralNameList(PRArenaPool * arena,CERTGeneralName ** pdst,CERTGeneralName * src)2685 CERT_CopyGeneralNameList(PRArenaPool *arena, CERTGeneralName **pdst, CERTGeneralName *src)
2686 {
2687     SECStatus result = SECSuccess;
2688     void *mark = NULL;
2689     CERTGeneralName *src_head, *dst_head;
2690     CERTGeneralName *cur, *prev;
2691 
2692     /*
2693      * NSS WART
2694      * There is no publice API to copy a list of GeneralNames.
2695      *
2696      * GeneralNames are an exception to all other NSS data containers.
2697      * Normally homogeneous collections are stored in a array of pointers to
2698      * the items with the last array element being NULL. However GeneralNames are
2699      * exception, they embed a linked list for assembling them in a list. Not only
2700      * is this an awkward deviation but it means the GeneralName cannot belong to
2701      * more than one collection.
2702      *
2703      * The logic here is copied from CERT_CopyGeneralName in certdb/genname.c
2704      *
2705      * The linked list is circular. The logic to stop traversal is if the link
2706      * pointed to by CERT_GetNextGeneralName/CERT_GetPrevGeneralName is the same
2707      * as the GeneralName the traversal started with.
2708      */
2709 
2710     if (!arena) {
2711 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
2712         return SECFailure;
2713     }
2714 
2715     if (!src) {
2716 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
2717         return SECFailure;
2718     }
2719 
2720     mark = PORT_ArenaMark(arena);
2721 
2722     src_head = src;
2723     dst_head = cur = NULL;
2724     do {
2725         prev = cur;
2726         if (CERT_CopyGeneralName(arena, &cur, src) != SECSuccess) {
2727             result = SECFailure;
2728             goto exit;
2729         }
2730         if (dst_head == NULL) { /* first node */
2731             dst_head = cur;
2732             prev = cur;
2733         }
2734 
2735         cur->l.next = &dst_head->l; /* tail node's next points to head */
2736         cur->l.prev = &prev->l;     /* tail node's prev points to prev */
2737         dst_head->l.prev = &cur->l; /* head's prev points to tail node */
2738         prev->l.next = &cur->l;     /* prev node's next point to tail node */
2739 
2740         src = CERT_GetNextGeneralName(src);
2741     } while (src != src_head);
2742 
2743  exit:
2744     if (result == SECSuccess) {
2745         *pdst = dst_head;
2746         PORT_ArenaUnmark(arena, mark);
2747     } else {
2748         *pdst = NULL;
2749         PORT_ArenaRelease(arena, mark);
2750     }
2751     return result;
2752 }
2753 
2754 static SECStatus
CERT_CopyCRLDistributionPoint(PRArenaPool * arena,CRLDistributionPoint ** pdst,CRLDistributionPoint * src)2755 CERT_CopyCRLDistributionPoint(PRArenaPool *arena, CRLDistributionPoint **pdst, CRLDistributionPoint *src)
2756 {
2757     SECStatus result = SECSuccess;
2758     CERTRDN *rdn;
2759     void *mark = NULL;
2760     CRLDistributionPoint *dst;
2761     SECItem tmp_item;
2762 
2763     /*
2764      * NSS WART
2765      * There is no public API to create a CRLDistributionPoint or copy it.
2766      */
2767     mark = PORT_ArenaMark(arena);
2768 
2769     if ((dst = PORT_ArenaZNew(arena, CRLDistributionPoint)) == NULL) {
2770         result = SECFailure;
2771         goto exit;
2772     }
2773 
2774     switch((dst->distPointType = src->distPointType)) {
2775     case generalName:
2776         if ((result = CERT_CopyGeneralNameList(arena,
2777                                                &dst->distPoint.fullName,
2778                                                src->distPoint.fullName)) != SECSuccess) {
2779             goto exit;
2780         }
2781         break;
2782     case relativeDistinguishedName:
2783         if ((rdn = CERT_CreateRDN(arena, NULL)) == NULL) {
2784             result = SECFailure;
2785             goto exit;
2786         }
2787         dst->distPoint.relativeName = *rdn;
2788         if ((result = CERT_CopyRDN(arena,
2789                                    &dst->distPoint.relativeName,
2790                                    &src->distPoint.relativeName)) != SECSuccess) {
2791             goto exit;
2792         }
2793         break;
2794     default:
2795         PORT_SetError(SEC_ERROR_INVALID_ARGS);
2796         result = SECFailure;
2797         goto exit;
2798     }
2799 
2800     if ((result = SECITEM_CopyItem(arena, &dst->reasons, &src->reasons)) != SECSuccess) {
2801         goto exit;
2802     }
2803 
2804     /*
2805      * WARNING: NSS WART
2806      * src->bitsmap is a SECItem whose length is a bit count and whose data
2807      * omits the leading DER bitstring "unused" octet.
2808      */
2809 
2810     tmp_item = src->bitsmap;
2811     DER_ConvertBitString(&tmp_item); /* make len a byte count */
2812     if ((result = SECITEM_CopyItem(arena, &dst->bitsmap, &tmp_item)) != SECSuccess) {
2813         goto exit;
2814     }
2815     dst->bitsmap.len = src->bitsmap.len;
2816 
2817     if (src->crlIssuer) {
2818         if ((result = CERT_CopyGeneralName(arena, &dst->crlIssuer, src->crlIssuer)) != SECSuccess) {
2819             goto exit;
2820         }
2821     }
2822 
2823     /*
2824      * WARNING: we don't copy these because they're only used during decoding:
2825      * derDistPoint, derRelativeName, derCrlIssuer, derFullName
2826      */
2827 
2828  exit:
2829     if (result == SECSuccess) {
2830         *pdst = dst;
2831         PORT_ArenaUnmark(arena, mark);
2832     } else {
2833         *pdst = NULL;
2834         PORT_ArenaRelease(arena, mark);
2835     }
2836     return result;
2837 }
2838 
2839 /*
2840  * NSS WART
2841  * There is no public API to copy a CERTAuthKeyID
2842  */
2843 static SECStatus
CERT_CopyAuthKeyID(PRArenaPool * arena,CERTAuthKeyID ** pdst,CERTAuthKeyID * src)2844 CERT_CopyAuthKeyID(PRArenaPool *arena, CERTAuthKeyID **pdst, CERTAuthKeyID *src)
2845 {
2846     SECStatus result = SECSuccess;
2847     void *mark = NULL;
2848     CERTAuthKeyID *dst;
2849 
2850     mark = PORT_ArenaMark(arena);
2851 
2852     if ((dst = PORT_ArenaZNew(arena, CERTAuthKeyID)) == NULL) {
2853         result = SECFailure;
2854         goto exit;
2855     }
2856 
2857     if ((result = SECITEM_CopyItem(arena, &dst->keyID, &src->keyID)) != SECSuccess) {
2858         goto exit;
2859     }
2860 
2861     if ((result = CERT_CopyGeneralNameList(arena, &dst->authCertIssuer,
2862                                            src->authCertIssuer)) != SECSuccess) {
2863         goto exit;
2864     }
2865 
2866     if ((result = SECITEM_CopyItem(arena, &dst->authCertSerialNumber,
2867                                    &src->authCertSerialNumber)) != SECSuccess) {
2868         goto exit;
2869     }
2870 
2871  exit:
2872     if (result == SECSuccess) {
2873         *pdst = dst;
2874         PORT_ArenaUnmark(arena, mark);
2875     } else {
2876         *pdst = NULL;
2877         PORT_ArenaRelease(arena, mark);
2878     }
2879     return result;
2880 }
2881 
2882 /*
2883  * NSS WART
2884  * There is no public API to copy a CERTAuthInfoAccess
2885  */
2886 static SECStatus
CERT_CopyAuthInfoAccess(PRArenaPool * arena,CERTAuthInfoAccess ** pdst,CERTAuthInfoAccess * src)2887 CERT_CopyAuthInfoAccess(PRArenaPool *arena, CERTAuthInfoAccess **pdst, CERTAuthInfoAccess *src)
2888 {
2889     SECStatus result = SECSuccess;
2890     void *mark = NULL;
2891     CERTAuthInfoAccess *dst;
2892 
2893     mark = PORT_ArenaMark(arena);
2894 
2895     if ((dst = PORT_ArenaZNew(arena, CERTAuthInfoAccess)) == NULL) {
2896         result = SECFailure;
2897         goto exit;
2898     }
2899 
2900     if ((result = SECITEM_CopyItem(arena, &dst->method, &src->method)) != SECSuccess) {
2901         goto exit;
2902     }
2903 
2904     if ((result = SECITEM_CopyItem(arena, &dst->derLocation, &src->derLocation)) != SECSuccess) {
2905         goto exit;
2906     }
2907 
2908     if ((result = CERT_CopyGeneralName(arena, &dst->location, src->location)) != SECSuccess) {
2909         goto exit;
2910     }
2911 
2912  exit:
2913     if (result == SECSuccess) {
2914         *pdst = dst;
2915         PORT_ArenaUnmark(arena, mark);
2916     } else {
2917         *pdst = NULL;
2918         PORT_ArenaRelease(arena, mark);
2919     }
2920     return result;
2921 }
2922 
2923 static int
oid_tag_from_name(const char * name)2924 oid_tag_from_name(const char *name)
2925 {
2926     PyObject *py_name;
2927     PyObject *py_lower_name;
2928     PyObject *py_value;
2929     int oid_tag;
2930 
2931     if ((py_name = PyUnicode_FromString(name)) == NULL) {
2932         return -1;
2933     }
2934 
2935     if ((py_lower_name = PyUnicode_Lower(py_name)) == NULL) {
2936         Py_DECREF(py_name);
2937         return -1;
2938     }
2939 
2940     if ((py_value = PyDict_GetItem(sec_oid_name_to_value, py_lower_name)) == NULL) {
2941 	PyErr_Format(PyExc_KeyError, "oid tag name not found: %s", name);
2942         Py_DECREF(py_name);
2943         Py_DECREF(py_lower_name);
2944         return -1;
2945     }
2946 
2947     oid_tag = PyLong_AsLong(py_value);
2948 
2949     Py_DECREF(py_name);
2950     Py_DECREF(py_lower_name);
2951 
2952     return oid_tag;
2953 }
2954 
2955 static PyObject *
oid_tag_to_pystr_name(int oid_tag)2956 oid_tag_to_pystr_name(int oid_tag)
2957 {
2958     PyObject *py_value;
2959     PyObject *py_name;
2960 
2961     if ((py_value = PyLong_FromLong(oid_tag)) == NULL) {
2962         return NULL;
2963     }
2964 
2965     if ((py_name = PyDict_GetItem(sec_oid_value_to_name, py_value)) == NULL) {
2966 	PyErr_Format(PyExc_KeyError, "oid tag not found: %#x", oid_tag);
2967         Py_DECREF(py_value);
2968         return NULL;
2969     }
2970 
2971     Py_DECREF(py_value);
2972     Py_INCREF(py_name);
2973 
2974     return py_name;
2975 }
2976 
2977 static int
get_oid_tag_from_object(PyObject * obj)2978 get_oid_tag_from_object(PyObject *obj)
2979 {
2980     int oid_tag = SEC_OID_UNKNOWN;
2981 
2982     if (PyBaseString_Check(obj)) {
2983         PyObject *py_obj_string_utf8 = NULL;
2984         char *type_string;
2985 
2986         py_obj_string_utf8 = PyBaseString_UTF8(obj, "OID Tag");
2987 
2988         if ((type_string = PyBytes_AsString(py_obj_string_utf8)) == NULL) {
2989             Py_DECREF(py_obj_string_utf8);
2990             return -1;
2991         }
2992 
2993         /*
2994          * First see if it's a canonical name,
2995          * if not try a dotted-decimal OID,
2996          * if not then try tag name.
2997          */
2998         if ((oid_tag = ava_name_to_oid_tag(type_string)) == SEC_OID_UNKNOWN) {
2999             if (is_oid_string(type_string)) { /* is dotted-decimal OID */
3000                 SECItem item;
3001 
3002                 item.data = NULL;
3003                 item.len = 0;
3004 
3005                 /* Convert dotted-decimal OID string to SECItem */
3006                 if (SEC_StringToOID(NULL, &item, type_string, 0) != SECSuccess) {
3007                     PyErr_Format(PyExc_ValueError, "failed to convert oid string \"%s\" to SECItem",
3008                                  type_string);
3009                     Py_DECREF(py_obj_string_utf8);
3010                     return -1;
3011                 }
3012                 /* Get the OID tag from the SECItem */
3013                 oid_tag = SECOID_FindOIDTag(&item);
3014                 SECITEM_FreeItem(&item, PR_FALSE);
3015             } else {
3016                 oid_tag = oid_tag_from_name(type_string);
3017             }
3018         }
3019 	Py_DECREF(py_obj_string_utf8);
3020     } else if (PyInteger_Check(obj)) {
3021         oid_tag = PyLong_AsLong(obj);
3022     } else if (PySecItem_Check(obj)) {
3023         oid_tag = SECOID_FindOIDTag(&((SecItem *)obj)->item);
3024     } else {
3025         PyErr_Format(PyExc_TypeError, "oid must be a string, an integer, or a SecItem, not %.200s",
3026                      Py_TYPE(obj)->tp_name);
3027         return -1;
3028     }
3029 
3030     return oid_tag;
3031 }
3032 
3033 static bool
is_oid_string(const char * oid_string)3034 is_oid_string(const char *oid_string)
3035 {
3036     const char *p;
3037     int n_integers, n_dots;
3038 
3039     n_integers = n_dots = 0;
3040     p = oid_string;
3041     if (strncasecmp("OID.", p, 4) == 0) p += 4;    /* skip optional OID. prefix */
3042     while (*p) {
3043         if (isdigit(*p)) {
3044             n_integers++;
3045             for (p++; *p && isdigit(*p); p++); /* consume rest of digits in integer */
3046         } else if (*p == '.') {                /* found a dot */
3047             n_dots++;
3048             p++;
3049         } else {                               /* not a dot or digit */
3050             if (isspace(*p)) {                 /* permit trailing white space */
3051                 for (p++; *p && isspace(*p); p++);
3052                 if (!*p) break;
3053             }
3054             return false;
3055         }
3056     }
3057 
3058     return (n_integers > 0) && (n_integers == n_dots+1);
3059 }
3060 
3061 static const char *
ava_oid_tag_to_name(SECOidTag tag)3062 ava_oid_tag_to_name(SECOidTag tag)
3063 {
3064     const DnAvaProps *ava = dn_ava_props;
3065 
3066     for (ava = dn_ava_props;
3067          ava->oid_tag != tag && ava->oid_tag != SEC_OID_UNKNOWN;
3068          ava++);
3069 
3070     return (ava->oid_tag != SEC_OID_UNKNOWN) ? ava->name : NULL;
3071 }
3072 
3073 static int
ava_oid_tag_to_value_type(SECOidTag tag)3074 ava_oid_tag_to_value_type(SECOidTag tag)
3075 {
3076     const DnAvaProps *ava = dn_ava_props;
3077 
3078     for (ava = dn_ava_props;
3079          ava->oid_tag != tag && ava->oid_tag != SEC_OID_UNKNOWN;
3080          ava++);
3081 
3082     return (ava->oid_tag != SEC_OID_UNKNOWN) ? ava->value_type : SEC_ASN1_UTF8_STRING;
3083 }
3084 
3085 /*
3086  * Given a canonical ava name (e.g. "CN") return the oid tag for it. Case
3087  * is not significant. If not found SEC_OID_UNKNOWN is returned.
3088  */
3089 static SECOidTag
ava_name_to_oid_tag(const char * name)3090 ava_name_to_oid_tag(const char *name)
3091 {
3092     const DnAvaProps *ava = dn_ava_props;
3093 
3094     for (ava = dn_ava_props;
3095          ava->oid_tag != SEC_OID_UNKNOWN && strcasecmp(ava->name, name);
3096          ava++);
3097 
3098     return ava->oid_tag;
3099 }
3100 
3101 static int
_AddIntConstantWithLookup(PyObject * module,const char * name,long value,const char * prefix,PyObject * name_to_value,PyObject * value_to_name)3102 _AddIntConstantWithLookup(PyObject *module, const char *name, long value, const char *prefix,
3103                           PyObject *name_to_value, PyObject *value_to_name)
3104 {
3105     int result = 0;
3106     PyObject *module_dict;
3107     PyObject *py_name = NULL;
3108     PyObject *py_name_sans_prefix = NULL;
3109     PyObject *py_lower_name = NULL;
3110     PyObject *py_value = NULL;
3111     PyObject *py_prefix = NULL;
3112     PyObject *py_lower_prefix = NULL;
3113 
3114     if (!PyModule_Check(module)) {
3115         PyErr_SetString(PyExc_TypeError, "_AddIntConstantWithLookup() needs module as first arg");
3116         result = -1;
3117         goto exit;
3118     }
3119 
3120     if ((module_dict = PyModule_GetDict(module)) == NULL) {
3121         PyErr_Format(PyExc_SystemError, "module '%s' has no __dict__",
3122                      PyModule_GetName(module));
3123         result = -1;
3124         goto exit;
3125     }
3126 
3127     if ((py_name = PyUnicode_FromString(name)) == NULL) {
3128         result = -1;
3129         goto exit;
3130     }
3131 
3132     if ((py_lower_name = PyUnicode_Lower(py_name)) == NULL) {
3133         result = -1;
3134         goto exit;
3135     }
3136 
3137     if ((py_value = PyLong_FromLong(value)) == NULL) {
3138         result = -1;
3139         goto exit;
3140     }
3141 
3142     if (PyDict_GetItem(module_dict, py_name)) {
3143         PyErr_Format(PyExc_SystemError, "module '%s' already contains %s",
3144                      PyModule_GetName(module), name);
3145         result = -1;
3146         goto exit;
3147     }
3148 
3149     if (PyDict_SetItem(module_dict, py_name, py_value) != 0) {
3150         result = -1;
3151         goto exit;
3152     }
3153 
3154     if (PyDict_SetItem(value_to_name, py_value, py_name) != 0) {
3155         result = -1;
3156         goto exit;
3157     }
3158 
3159     if (PyDict_SetItem(name_to_value, py_lower_name, py_value) != 0) {
3160         result = -1;
3161         goto exit;
3162     }
3163 
3164     if (prefix) {
3165         size_t prefix_len = strlen(prefix);
3166 
3167         if (strlen(name) > prefix_len &&
3168             strncasecmp(prefix, name, prefix_len) == 0) {
3169 
3170             if ((py_prefix = PyUnicode_FromString(prefix)) == NULL) {
3171                 result = -1;
3172                 goto exit;
3173             }
3174 
3175             if ((py_lower_prefix = PyUnicode_Lower(py_prefix)) == NULL) {
3176                 result = -1;
3177                 goto exit;
3178             }
3179 
3180             if ((py_name_sans_prefix = PyUnicode_Replace(py_lower_name, py_lower_prefix, py_empty_string, 1)) == NULL) {
3181                 result = -1;
3182                 goto exit;
3183             }
3184 
3185             if (PyDict_SetItem(name_to_value, py_name_sans_prefix, py_value) != 0) {
3186                 result = -1;
3187                 goto exit;
3188             }
3189         }
3190     }
3191 
3192  exit:
3193     Py_XDECREF(py_name);
3194     Py_XDECREF(py_name_sans_prefix);
3195     Py_XDECREF(py_lower_name);
3196     Py_XDECREF(py_value);
3197     Py_XDECREF(py_prefix);
3198     Py_XDECREF(py_lower_prefix);
3199 
3200     return result;
3201 
3202 }
3203 
3204 static int
_AddIntConstantAlias(const char * name,long value,PyObject * name_to_value)3205 _AddIntConstantAlias(const char *name, long value, PyObject *name_to_value)
3206 {
3207     int result = 0;
3208     PyObject *py_name = NULL;
3209     PyObject *py_lower_name = NULL;
3210     PyObject *py_value = NULL;
3211 
3212     if ((py_name = PyUnicode_FromString(name)) == NULL) {
3213         result = -1;
3214         goto exit;
3215     }
3216 
3217     if ((py_lower_name = PyUnicode_Lower(py_name)) == NULL) {
3218         result = -1;
3219         goto exit;
3220     }
3221 
3222     if ((py_value = PyLong_FromLong(value)) == NULL) {
3223         result = -1;
3224         goto exit;
3225     }
3226 
3227     if (PyDict_GetItem(name_to_value, py_name)) {
3228         PyErr_Format(PyExc_SystemError, "lookup dict already contains %s",
3229                      name);
3230         result = -1;
3231         goto exit;
3232     }
3233 
3234     if (PyDict_SetItem(name_to_value, py_lower_name, py_value) != 0) {
3235         result = -1;
3236         goto exit;
3237     }
3238 
3239 
3240  exit:
3241     Py_XDECREF(py_name);
3242     Py_XDECREF(py_lower_name);
3243     Py_XDECREF(py_value);
3244     return result;
3245 }
3246 
3247 /* Set object in thread local storage under name, return 0 for success, -1 on failure */
3248 static int
set_thread_local(const char * name,PyObject * obj)3249 set_thread_local(const char *name, PyObject *obj)
3250 {
3251     PyObject *tdict;
3252     PyObject *thread_local_dict;
3253 
3254     /* Get this threads thread local dict */
3255     if ((tdict = PyThreadState_GetDict()) == NULL) {
3256         PyErr_SetString(PyExc_RuntimeError, "cannot get thread state");
3257         return -1;
3258     }
3259 
3260     /* Get our (i.e. NSS's) thread local dict */
3261     if ((thread_local_dict = PyDict_GetItemString(tdict, NSS_THREAD_LOCAL_KEY)) == NULL) {
3262         /*
3263          * Our thread local dict does not yet exist so create it
3264          * and set it in the thread's thread local dict.
3265          */
3266         if ((thread_local_dict = PyDict_New()) == NULL) {
3267             PyErr_SetString(PyExc_RuntimeError, "cannot create thread local data dict");
3268             return -1;
3269         }
3270         if (PyDict_SetItemString(tdict, NSS_THREAD_LOCAL_KEY, thread_local_dict) < 0) {
3271             Py_DECREF(thread_local_dict);
3272             PyErr_SetString(PyExc_RuntimeError, "cannot store thread local data dict");
3273             return -1;
3274         }
3275     }
3276 
3277     if (PyDict_SetItemString(thread_local_dict, name, obj) < 0) {
3278         PyErr_SetString(PyExc_RuntimeError, "cannot store object in thread local data dict");
3279         return -1;
3280     }
3281 
3282     return 0;
3283 }
3284 
3285 /* Same return behavior as PyDict_GetItem() */
3286 static PyObject *
get_thread_local(const char * name)3287 get_thread_local(const char *name)
3288 {
3289     PyObject *tdict;
3290     PyObject *thread_local_dict;
3291 
3292     /* Get this threads thread local dict */
3293     if ((tdict = PyThreadState_GetDict()) == NULL) {
3294         PyErr_SetString(PyExc_RuntimeError, "cannot get thread state");
3295         return NULL;
3296     }
3297 
3298     /* Get our (i.e. NSS's) thread local dict */
3299     if ((thread_local_dict = PyDict_GetItemString(tdict, NSS_THREAD_LOCAL_KEY)) == NULL) {
3300         /*
3301          * Our thread local dict does not yet exist thus the item can't be
3302          * in the dict, thus it's not found.
3303          */
3304         return NULL;
3305     }
3306 
3307     return PyDict_GetItemString(thread_local_dict, name);
3308 }
3309 
3310 
3311 /* Remove named item from thread local storage, return 0 for success, -1 on failure */
3312 static int
del_thread_local(const char * name)3313 del_thread_local(const char *name)
3314 {
3315     PyObject *tdict;
3316     PyObject *thread_local_dict;
3317 
3318     /* Get this threads thread local dict */
3319     if ((tdict = PyThreadState_GetDict()) == NULL) {
3320         PyErr_SetString(PyExc_RuntimeError, "cannot get thread state");
3321         return -1;
3322     }
3323 
3324     /* Get our (i.e. NSS's) thread local dict */
3325     if ((thread_local_dict = PyDict_GetItemString(tdict, NSS_THREAD_LOCAL_KEY)) == NULL) {
3326         /*
3327          * Our thread local dict does not yet exist thus the item can't be
3328          * in the dict, thus it cannot be deleted, implicit success.
3329          */
3330         return 0;
3331     }
3332 
3333     return PyDict_DelItemString(thread_local_dict, name);
3334 }
3335 
3336 static int
PRTimeConvert(PyObject * obj,PRTime * param)3337 PRTimeConvert(PyObject *obj, PRTime *param)
3338 {
3339     PRTime time;
3340 
3341     if (PyFloat_Check(obj)) {
3342         LL_D2L(time, PyFloat_AsDouble(obj));
3343         *param = time;
3344         return 1;
3345     }
3346 
3347     if (PyInteger_Check(obj)) {
3348         LL_I2L(time, PyLong_AsLong(obj));
3349         *param = time;
3350         return 1;
3351     }
3352 
3353     if (PyNone_Check(obj)) {
3354         time = PR_Now();
3355         *param = time;
3356         return 1;
3357     }
3358 
3359     PyErr_Format(PyExc_TypeError, "must be int, float or None, not %.50s",
3360                  Py_TYPE(obj)->tp_name);
3361     return 0;
3362 }
3363 
3364 // FIXME, should invoke PK11_GetInternalKeySlot(), return PK11SlotInfo *slot;
3365 static int
PK11SlotOrNoneConvert(PyObject * obj,PyObject ** param)3366 PK11SlotOrNoneConvert(PyObject *obj, PyObject **param)
3367 {
3368     if (PyPK11Slot_Check(obj)) {
3369         *param = obj;
3370         return 1;
3371     }
3372 
3373     if (PyNone_Check(obj)) {
3374         *param = NULL;
3375         return 1;
3376     }
3377 
3378     PyErr_Format(PyExc_TypeError, "must be %.50s or None, not %.50s",
3379                  PK11SlotType.tp_name, Py_TYPE(obj)->tp_name);
3380     return 0;
3381 }
3382 
3383 static int
CertDBOrNoneConvert(PyObject * obj,PyObject ** param)3384 CertDBOrNoneConvert(PyObject *obj, PyObject **param)
3385 {
3386     if (PyCertDB_Check(obj)) {
3387         *param = obj;
3388         return 1;
3389     }
3390 
3391     if (PyNone_Check(obj)) {
3392         *param = NULL;
3393         return 1;
3394     }
3395 
3396     PyErr_Format(PyExc_TypeError, "must be %.50s or None, not %.50s",
3397                  SecItemType.tp_name, Py_TYPE(obj)->tp_name);
3398     return 0;
3399 }
3400 
3401 static int
TupleOrNoneConvert(PyObject * obj,PyObject ** param)3402 TupleOrNoneConvert(PyObject *obj, PyObject **param)
3403 {
3404     if (PyTuple_Check(obj)) {
3405         *param = obj;
3406         return 1;
3407     }
3408 
3409     if (PyNone_Check(obj)) {
3410         *param = NULL;
3411         return 1;
3412     }
3413 
3414     PyErr_Format(PyExc_TypeError, "must be %.50s or None, not %.50s",
3415                  PyTuple_Type.tp_name, Py_TYPE(obj)->tp_name);
3416     return 0;
3417 }
3418 
3419 static int
SymKeyOrNoneConvert(PyObject * obj,PyObject ** param)3420 SymKeyOrNoneConvert(PyObject *obj, PyObject **param)
3421 {
3422     if (PySymKey_Check(obj)) {
3423         *param = obj;
3424         return 1;
3425     }
3426 
3427     if (PyNone_Check(obj)) {
3428         *param = NULL;
3429         return 1;
3430     }
3431 
3432     PyErr_Format(PyExc_TypeError, "must be %.50s or None, not %.50s",
3433                  PK11SymKeyType.tp_name, Py_TYPE(obj)->tp_name);
3434     return 0;
3435 }
3436 
3437 /*
3438  * Note, this is only necessary in Py2, it is equivalent to the 's'
3439  * PyArg_Parse format conversion in Py3 with the exception a PyBytes
3440  * object is returned which must be DECREF'ed instead of returning a
3441  * char * pointer.
3442  */
3443 static int
UTF8Convert(PyObject * obj,PyObject ** param)3444 UTF8Convert(PyObject *obj, PyObject **param)
3445 {
3446     PyObject *py_utf8 = NULL;
3447 
3448     if (!obj) {
3449         *param = NULL;
3450         return 0;
3451     }
3452 
3453     if ((py_utf8 = PyBaseString_UTF8(obj, NULL)) != NULL) {
3454         *param = py_utf8;
3455         return 1;
3456     }
3457 
3458     return 0;
3459 }
3460 
3461 /*
3462  * Note, this is only necessary in Py2, it is equivalent to the 'z'
3463  * PyArg_Parse format conversion in Py3 with the exception a PyBytes
3464  * object is returned (if obj is non-NULL or not None) which must be
3465  * DECREF'ed instead of returning a char * pointer.
3466  */
3467 static int
UTF8OrNoneConvert(PyObject * obj,PyObject ** param)3468 UTF8OrNoneConvert(PyObject *obj, PyObject **param)
3469 {
3470     PyObject *py_utf8 = NULL;
3471 
3472     if (!obj) {
3473         *param = NULL;
3474         return 1;
3475     }
3476 
3477     if (PyNone_Check(obj)) {
3478         *param = NULL;
3479         return 1;
3480     }
3481 
3482     if ((py_utf8 = PyBaseString_UTF8(obj, NULL)) != NULL) {
3483         *param = py_utf8;
3484         return 1;
3485     }
3486 
3487     return 0;
3488 }
3489 
3490 static const char *
pk11_disabled_reason_str(PK11DisableReasons reason)3491 pk11_disabled_reason_str(PK11DisableReasons reason)
3492 {
3493     static char buf[80];
3494 
3495     switch(reason) {
3496     case PK11_DIS_NONE:
3497         return _("no reason");
3498     case PK11_DIS_USER_SELECTED:
3499         return _("user disabled");
3500     case PK11_DIS_COULD_NOT_INIT_TOKEN:
3501         return _("could not initialize token");
3502     case PK11_DIS_TOKEN_VERIFY_FAILED:
3503         return _("could not verify token");
3504     case PK11_DIS_TOKEN_NOT_PRESENT:
3505         return _("token not present");
3506     default:
3507         snprintf(buf, sizeof(buf), "unknown(%#x)", reason);
3508         return buf;
3509     }
3510 }
3511 
3512 static const char *
pk11_disabled_reason_name(PK11DisableReasons reason)3513 pk11_disabled_reason_name(PK11DisableReasons reason)
3514 {
3515     static char buf[80];
3516 
3517     switch(reason) {
3518     case PK11_DIS_NONE:                 return "PK11_DIS_NONE";
3519     case PK11_DIS_USER_SELECTED:        return "PK11_DIS_USER_SELECTED";
3520     case PK11_DIS_COULD_NOT_INIT_TOKEN: return "PK11_DIS_COULD_NOT_INIT_TOKEN";
3521     case PK11_DIS_TOKEN_VERIFY_FAILED:  return "PK11_DIS_TOKEN_VERIFY_FAILED";
3522     case PK11_DIS_TOKEN_NOT_PRESENT:    return "PK11_DIS_TOKEN_NOT_PRESENT";
3523     default:
3524         snprintf(buf, sizeof(buf), "unknown(%#x)", reason);
3525         return buf;
3526     }
3527 }
3528 
3529 static const char *
key_type_str(KeyType key_type)3530 key_type_str(KeyType key_type)
3531 {
3532     static char buf[80];
3533 
3534     switch(key_type) {
3535     case nullKey:     return "NULL";
3536     case rsaKey:      return "RSA";
3537     case dsaKey:      return "DSA";
3538     case fortezzaKey: return "Fortezza";
3539     case dhKey:       return "Diffie Helman";
3540     case keaKey:      return "Key Exchange Algorithm";
3541     case ecKey:       return "Elliptic Curve";
3542     default:
3543         snprintf(buf, sizeof(buf), "unknown(%#x)", key_type);
3544         return buf;
3545     }
3546 }
3547 
3548 
3549 static const char *
oid_tag_str(SECOidTag tag)3550 oid_tag_str(SECOidTag tag)
3551 {
3552     static char buf[80];
3553 
3554     SECOidData *oiddata;
3555 
3556     if ((oiddata = SECOID_FindOIDByTag(tag)) != NULL) {
3557 	return oiddata->desc;
3558     }
3559     snprintf(buf, sizeof(buf), "unknown(%#x)", tag);
3560     return buf;
3561 }
3562 
3563 static PyObject *
obj_sprintf(const char * fmt,...)3564 obj_sprintf(const char *fmt, ...)
3565 {
3566     va_list va;
3567     Py_ssize_t n_fmts, i;
3568     PyObject *args = NULL;
3569     PyObject *obj = NULL;
3570     PyObject *py_fmt = NULL;
3571     PyObject *result = NULL;
3572     const char *s;
3573 
3574     for (s = fmt, n_fmts = 0; *s; s++) {
3575         if (*s == '%') {
3576             if (s > fmt) {
3577                 if (s[-1] != '%') {
3578                     n_fmts++;
3579                 }
3580             } else {
3581                 n_fmts++;
3582             }
3583         }
3584     }
3585 
3586     if ((args = PyTuple_New(n_fmts)) == NULL) {
3587         return NULL;
3588     }
3589 
3590     va_start(va, fmt);
3591     for (i = 0; i < n_fmts; i++) {
3592         obj = va_arg(va, PyObject *);
3593         Py_INCREF(obj);
3594         PyTuple_SetItem(args, i, obj);
3595     }
3596     va_end(va);
3597 
3598     if ((py_fmt = PyUnicode_FromString(fmt)) == NULL) {
3599         Py_DECREF(args);
3600         return NULL;
3601     }
3602 
3603     result = PyUnicode_Format(py_fmt, args);
3604     Py_DECREF(py_fmt);
3605     Py_DECREF(args);
3606 
3607     return result;
3608 }
3609 
3610 static PyObject *
obj_to_hex(PyObject * obj,int octets_per_line,char * separator)3611 obj_to_hex(PyObject *obj, int octets_per_line, char *separator)
3612 {
3613     Py_buffer view;
3614     PyObject *result = NULL;
3615 
3616     if (!PyObject_CheckBuffer(obj)) {
3617         PyErr_Format(PyExc_TypeError, "object must support the buffer protocol");
3618         return NULL;
3619     }
3620 
3621     view.obj = NULL;
3622     if (PyObject_GetBuffer(obj, &view, PyBUF_SIMPLE) != 0) {
3623         return NULL;
3624     }
3625 
3626     result = raw_data_to_hex(view.buf, view.len, octets_per_line, separator);
3627     PyBuffer_Release(&view);
3628     return result;
3629 
3630 }
3631 
3632 /* see cert_data_to_hex() for documentation */
3633 static PyObject *
raw_data_to_hex(unsigned char * data,int data_len,int octets_per_line,char * separator)3634 raw_data_to_hex(unsigned char *data, int data_len, int octets_per_line, char *separator)
3635 {
3636     int separator_len = 0;
3637     char *separator_end = NULL;
3638     char *src=NULL, *dst=NULL;
3639     int line_size = 0;
3640     unsigned char octet = 0;
3641     int num_lines = 0;
3642     PyObject *lines = NULL;
3643     PyObject *line = NULL;
3644     PyObject *unicode_line = NULL;
3645     int line_number, i, j;
3646     int num_octets = 0;
3647 
3648     if (octets_per_line < 0)
3649         octets_per_line = 0;
3650 
3651     if (!separator)
3652         separator = "";
3653 
3654     separator_len = strlen(separator);
3655     separator_end = separator + separator_len;
3656 
3657     if (octets_per_line == 0) {
3658         num_octets = data_len;
3659         line_size = (num_octets * 2) + ((num_octets-1) * separator_len);
3660         if (line_size < 0) line_size = 0;
3661 
3662         if ((line = PyBytes_FromStringAndSize(NULL, line_size)) == NULL) {
3663             return NULL;
3664         }
3665         dst = PyBytes_AS_STRING(line);
3666         for (i = 0; i < data_len; i++) {
3667             octet = data[i];
3668             *dst++ = hex_chars[(octet & 0xF0) >> 4];
3669             *dst++ = hex_chars[octet & 0xF];
3670             if (i < data_len-1)
3671                 for (src = separator; src < separator_end; *dst++ = *src++);
3672         }
3673         unicode_line = PyUnicode_FromString(PyBytes_AS_STRING(line));
3674         Py_DECREF(line);
3675         return unicode_line;
3676     } else {
3677         num_lines = (data_len + octets_per_line - 1) / octets_per_line;
3678         if (num_lines < 0) num_lines = 0;
3679 
3680         if ((lines = PyList_New(num_lines)) == NULL) {
3681             return NULL;
3682         }
3683 
3684         for (i = line_number = 0; i < data_len;) {
3685             num_octets = data_len - i;
3686             if (num_octets > octets_per_line) {
3687                 num_octets = octets_per_line;
3688                 line_size = num_octets*(2+separator_len);
3689             } else {
3690                 line_size = (num_octets * 2) + ((num_octets-1) * separator_len);
3691             }
3692 
3693             if (line_size < 0) line_size = 0;
3694             if ((line = PyBytes_FromStringAndSize(NULL, line_size)) == NULL) {
3695                 Py_DECREF(lines);
3696                 return NULL;
3697             }
3698             dst = PyBytes_AS_STRING(line);
3699             for (j = 0; j < num_octets && i < data_len; i++, j++) {
3700                 octet = data[i];
3701                 *dst++ = hex_chars[(octet & 0xF0) >> 4];
3702                 *dst++ = hex_chars[octet & 0xF];
3703                 if (i < data_len-1)
3704                     for (src = separator; src < separator_end; *dst++ = *src++);
3705             }
3706             if ((unicode_line = PyUnicode_FromString(PyBytes_AS_STRING(line))) == NULL) {
3707                 Py_DECREF(line);
3708                 Py_DECREF(lines);
3709             }
3710             Py_DECREF(line);
3711             PyList_SetItem(lines, line_number++, unicode_line);
3712         }
3713         return lines;
3714     }
3715 }
3716 
3717 PyDoc_STRVAR(cert_data_to_hex_doc,
3718 "data_to_hex(data, octets_per_line=0, separator=':') -> string or list of strings\n\
3719 \n\
3720 :Parameters:\n\
3721     data : buffer\n\
3722         Binary data\n\
3723     octets_per_line : integer\n\
3724         Number of octets formatted on one line, if 0 then\n\
3725         return a single string instead of an array of lines\n\
3726     separator : string\n\
3727         String used to seperate each octet\n\
3728         If None it will be as if the empty string had been\n\
3729         passed and no separator will be used.\n\
3730 \n\
3731 Format the binary data as hex string(s).\n\
3732 Either a list of strings is returned or a single string.\n\
3733 \n\
3734 If octets_per_line is greater than zero then a list of\n\
3735 strings will be returned where each string contains\n\
3736 octets_per_line number of octets (except for the last\n\
3737 string in the list which will contain the remainder of the\n\
3738 octets). Returning a list of \"lines\" makes it convenient\n\
3739 for a caller to format a block of hexadecimal data with line\n\
3740 wrapping. If octets_per_line is greater than zero indicating\n\
3741 a list result is desired a list is always returned even if\n\
3742 the number of octets would produce only a single line.\n\
3743 \n\
3744 If octets_per_line is zero then a single string is returned,\n\
3745 (no line splitting is performed). This is the default.\n\
3746 \n\
3747 The separator string is used to separate each octet. If None\n\
3748 it will be as if the empty string had been passed and no\n\
3749 separator will be used.\n\
3750 ");
3751 
3752 static PyObject *
cert_data_to_hex(PyObject * self,PyObject * args,PyObject * kwds)3753 cert_data_to_hex(PyObject *self, PyObject *args, PyObject *kwds)
3754 {
3755     static char *kwlist[] = {"data", "octets_per_line", "separator", NULL};
3756     PyObject *obj = NULL;
3757     int octets_per_line = 0;
3758     char *separator = HEX_SEPARATOR_DEFAULT;
3759 
3760     TraceMethodEnter(self);
3761 
3762     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|iz:cert_data_to_hex", kwlist,
3763                                      &obj, &octets_per_line, &separator))
3764         return NULL;
3765 
3766     return obj_to_hex(obj, octets_per_line, separator);
3767 }
3768 
3769 PyDoc_STRVAR(read_hex_doc,
3770 "read_hex(input, separators=\" ,:\\t\\n\") -> buffer\n\
3771 \n\
3772 :Parameters:\n\
3773     input : string\n\
3774         string containing hexadecimal data\n\
3775     separators : string or None\n\
3776         string containing set of separator characters\n\
3777         Any character encountered during parsing which is in\n\
3778         this string will be skipped and considered a separator\n\
3779         between pairs of hexadecimal characters.\n\
3780 \n\
3781 Parse a string containing hexadecimal data and return a buffer\n\
3782 object containing the binary octets. Each octet in the string is\n\
3783 represented as a pair of case insensitive hexadecimal characters\n\
3784 (0123456789abcdef). Each octet must be a pair of\n\
3785 characters. Octets may optionally be preceded by 0x or 0X. Octets\n\
3786 may be separated by separator characters specified in the\n\
3787 separators string. The separators string is a set of\n\
3788 characters. Any character in the separators character set will be\n\
3789 ignored when it occurs between octets. If no separators should be\n\
3790 considered then pass an empty string.\n\
3791 \n\
3792 Using the default separators each of these strings is valid input\n\
3793 representing the same 8 octet sequence:\n\
3794 \n\
3795 01, 23, 45, 67, 89, ab, cd, ef\n\
3796 01, 23, 45, 67, 89, AB, CD, EF\n\
3797 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef\n\
3798 01:23:45:67:89:ab:cd:ef\n\
3799 0123456789abcdef\n\
3800 01 23 45 67 89 ab cd ef\n\
3801 0x010x230x450x670x890xab0xcd0xef\n\
3802 ");
3803 static PyObject *
read_hex(PyObject * self,PyObject * args,PyObject * kwds)3804 read_hex(PyObject *self, PyObject *args, PyObject *kwds)
3805 {
3806     static char *kwlist[] = {"input", "separators", NULL};
3807     const char *input;
3808     const char *separators = " ,:\t\n";
3809     size_t input_len, separators_len;
3810     Py_ssize_t n_octets;
3811     unsigned char octet, *data;
3812     const char *src, *input_end;
3813     const char *sep, *separators_end;
3814     PyObject *py_out_buf;
3815 
3816     TraceMethodEnter(self);
3817 
3818     if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|s:read_hex", kwlist,
3819                                      &input, &separators))
3820         return NULL;
3821 
3822     input_len = strlen(input);
3823     src = input;
3824     input_end = input + input_len;
3825     separators_len = strlen(separators);
3826     n_octets = 0;
3827 
3828     /*
3829      * The maximum number of octets is half the string length
3830      * because they must occur in pairs. If there are separators
3831      * in the string then the number of octets will be less than
3832      * half. Thus len/2 is an upper bound.
3833      */
3834     if ((data = PyMem_Malloc(input_len/2)) == NULL) {
3835         return PyErr_NoMemory();
3836     }
3837 
3838     separators_end = separators + separators_len;
3839     while (src < input_end) {
3840         for (; *src; src++) {
3841             for (sep = separators; sep < separators_end && *src != *sep; sep++);
3842             if (sep == separators_end) break;
3843         }
3844         if (!*src) break;
3845         if (src[0] == '0' && (tolower(src[1]) == 'x')) src +=2; /* skip 0x or 0X */
3846         octet = 0;
3847         switch (tolower(src[0])) {
3848         case '0': octet = 0x0 << 4; break;
3849         case '1': octet = 0x1 << 4; break;
3850         case '2': octet = 0x2 << 4; break;
3851         case '3': octet = 0x3 << 4; break;
3852         case '4': octet = 0x4 << 4; break;
3853         case '5': octet = 0x5 << 4; break;
3854         case '6': octet = 0x6 << 4; break;
3855         case '7': octet = 0x7 << 4; break;
3856         case '8': octet = 0x8 << 4; break;
3857         case '9': octet = 0x9 << 4; break;
3858         case 'a': octet = 0xa << 4; break;
3859         case 'b': octet = 0xb << 4; break;
3860         case 'c': octet = 0xc << 4; break;
3861         case 'd': octet = 0xd << 4; break;
3862         case 'e': octet = 0xe << 4; break;
3863         case 'f': octet = 0xf << 4; break;
3864         default:
3865             PyMem_Free(data);
3866             PyErr_Format(PyExc_ValueError, "invalid hexadecimal string beginning at offset %td \"%s\"",
3867                          src - input, src);
3868             return NULL;
3869         }
3870         switch (tolower(src[1])) {
3871         case '0': octet |= 0x0; break;
3872         case '1': octet |= 0x1; break;
3873         case '2': octet |= 0x2; break;
3874         case '3': octet |= 0x3; break;
3875         case '4': octet |= 0x4; break;
3876         case '5': octet |= 0x5; break;
3877         case '6': octet |= 0x6; break;
3878         case '7': octet |= 0x7; break;
3879         case '8': octet |= 0x8; break;
3880         case '9': octet |= 0x9; break;
3881         case 'a': octet |= 0xa; break;
3882         case 'b': octet |= 0xb; break;
3883         case 'c': octet |= 0xc; break;
3884         case 'd': octet |= 0xd; break;
3885         case 'e': octet |= 0xe; break;
3886         case 'f': octet |= 0xf; break;
3887         default:
3888             PyMem_Free(data);
3889             PyErr_Format(PyExc_ValueError, "invalid hexadecimal string beginning at offset %td \"%s\"",
3890                          src - input, src);
3891             return NULL;
3892         }
3893         src += 2;
3894         data[n_octets++] = octet;
3895     }
3896 
3897     if ((py_out_buf = PyBytes_FromStringAndSize((char *)data, n_octets)) == NULL) {
3898         PyMem_Free(data);
3899         return NULL;
3900     }
3901     PyMem_Free(data);
3902 
3903     return py_out_buf;
3904 }
3905 
3906 static SECStatus
sec_strip_tag_and_length(SECItem * item)3907 sec_strip_tag_and_length(SECItem *item)
3908 {
3909     unsigned int start;
3910 
3911     if (!item || !item->data || item->len < 2) { /* must be at least tag and length */
3912         return SECFailure;
3913     }
3914     start = ((item->data[1] & 0x80) ? (item->data[1] & 0x7f) + 2 : 2);
3915     if (item->len < start) {
3916         return SECFailure;
3917     }
3918     item->data += start;
3919     item->len  -= start;
3920     return SECSuccess;
3921 }
3922 
3923 /* ================== Convert NSS Object to Python String =================== */
3924 
3925 static PyObject *
CERTName_to_pystr(CERTName * cert_name)3926 CERTName_to_pystr(CERTName *cert_name)
3927 {
3928     char *name;
3929     PyObject *py_name = NULL;
3930 
3931     if (!cert_name) {
3932         return PyUnicode_FromString("");
3933     }
3934 
3935     if ((name = CERT_NameToAscii(cert_name)) == NULL) {
3936         return PyUnicode_FromString("");
3937     }
3938 
3939     py_name = PyUnicode_FromString(name);
3940     PORT_Free(name);
3941     return py_name;
3942 }
3943 
3944 
3945 static PyObject *
der_context_specific_secitem_to_pystr(SECItem * item)3946 der_context_specific_secitem_to_pystr(SECItem *item)
3947 {
3948     PyObject *py_str = NULL;
3949     PyObject *hex_str = NULL;
3950     int type        = item->data[0] & SEC_ASN1_TAGNUM_MASK;
3951     int constructed = item->data[0] & SEC_ASN1_CONSTRUCTED;
3952     SECItem tmp;
3953 
3954     if (constructed) {
3955         py_str = PyUnicode_FromFormat("[%d]", type);
3956     } else {
3957         tmp = *item;
3958         if (sec_strip_tag_and_length(&tmp) == SECSuccess) {
3959             if ((hex_str = raw_data_to_hex(tmp.data, tmp.len, 0, HEX_SEPARATOR_DEFAULT))) {
3960                 py_str = PyUnicode_FromFormat("[%d] %U", type, hex_str);
3961                 Py_DECREF(hex_str);
3962             }
3963         }
3964         if (!py_str) {
3965             py_str = PyUnicode_FromFormat("[%d]", type);
3966         }
3967     }
3968 
3969     return py_str;
3970 }
3971 
3972 static PyObject *
secitem_to_pystr_hex(SECItem * item)3973 secitem_to_pystr_hex(SECItem *item)
3974 {
3975     return raw_data_to_hex(item->data, item->len, 0, HEX_SEPARATOR_DEFAULT);
3976 }
3977 
3978 static PyObject *
der_any_secitem_to_pystr(SECItem * item)3979 der_any_secitem_to_pystr(SECItem *item)
3980 {
3981     if (item && item->len && item->data) {
3982 	switch (item->data[0] & SEC_ASN1_CLASS_MASK) {
3983 	case SEC_ASN1_CONTEXT_SPECIFIC:
3984 	    return der_context_specific_secitem_to_pystr(item);
3985 	    break;
3986 	case SEC_ASN1_UNIVERSAL:
3987 	    return der_universal_secitem_to_pystr(item);
3988 	    break;
3989 	default:
3990 	    return raw_data_to_hex(item->data, item->len, 0, HEX_SEPARATOR_DEFAULT);
3991 	}
3992     }
3993     return PyUnicode_FromString("(null)");
3994 }
3995 
3996 
3997 /* return a ASN1 SET or SEQUENCE as a list of strings */
3998 static PyObject *
der_set_or_str_secitem_to_pylist_of_pystr(SECItem * item)3999 der_set_or_str_secitem_to_pylist_of_pystr(SECItem *item)
4000 {
4001     int constructed = item->data[0] & SEC_ASN1_CONSTRUCTED;
4002     SECItem stripped_item = *item;
4003     PyObject *py_items = NULL;
4004     PyObject *py_item = NULL;
4005 
4006     if (!constructed) {
4007         return raw_data_to_hex(item->data, item->len, 0, HEX_SEPARATOR_DEFAULT);
4008     }
4009 
4010     if (sec_strip_tag_and_length(&stripped_item) != SECSuccess) {
4011         Py_RETURN_NONE;
4012     }
4013 
4014     if ((py_items = PyList_New(0)) == NULL) {
4015         return NULL;
4016     }
4017 
4018     while (stripped_item.len >= 2) {
4019 	SECItem  tmp_item = stripped_item;
4020 
4021         if (tmp_item.data[1] & 0x80) {
4022 	    unsigned int i;
4023 	    unsigned int len = tmp_item.data[1] & 0x7f;
4024 	    if (len > sizeof tmp_item.len)
4025 	        break;
4026 	    tmp_item.len = 0;
4027 	    for (i = 0; i < len; i++) {
4028 		tmp_item.len = (tmp_item.len << 8) | tmp_item.data[2+i];
4029 	    }
4030 	    tmp_item.len += len + 2;
4031 	} else {
4032 	    tmp_item.len = tmp_item.data[1] + 2;
4033 	}
4034 	if (tmp_item.len > stripped_item.len) {
4035 	    tmp_item.len = stripped_item.len;
4036 	}
4037 	stripped_item.data += tmp_item.len;
4038 	stripped_item.len  -= tmp_item.len;
4039 
4040         py_item = der_any_secitem_to_pystr(&tmp_item);
4041         PyList_Append(py_items, py_item);
4042     }
4043 
4044     return py_items;
4045 }
4046 
4047 static PyObject *
boolean_secitem_to_pystr(SECItem * item)4048 boolean_secitem_to_pystr(SECItem *item)
4049 {
4050     int val = 0;
4051 
4052     if (item->data && item->len) {
4053 	val = item->data[0];
4054     }
4055 
4056     if (val)
4057         return PyUnicode_FromString("True");
4058     else
4059         return PyUnicode_FromString("False");
4060 }
4061 
4062 static PyObject *
der_boolean_secitem_to_pystr(SECItem * item)4063 der_boolean_secitem_to_pystr(SECItem *item)
4064 {
4065     PyObject *str = NULL;
4066     SECItem tmp_item = *item;
4067 
4068     if (sec_strip_tag_and_length(&tmp_item) == SECSuccess)
4069 	str = boolean_secitem_to_pystr(&tmp_item);
4070 
4071     return str;
4072 }
4073 
4074 /*
4075  * Decodes ASN1 integer. Properly handles large magnitude.
4076  *
4077  * item is a decoded ASN1 integer, if the integer is a DER encoded
4078  * integer with a tag and length then call encoded_integer_secitem_to_pylong
4079  */
4080 static PyObject *
integer_secitem_to_pylong(SECItem * item)4081 integer_secitem_to_pylong(SECItem *item)
4082 {
4083     int len;
4084     unsigned char *data, octet;
4085     PyObject *l = NULL;
4086     PyObject *eight = NULL;
4087     PyObject *new_bits = NULL;
4088     PyObject *tmp = NULL;
4089     bool negative;
4090 
4091     if (!item || !item->len || !item->data) {
4092         return PyLong_FromLong(0);
4093     }
4094 
4095     len = item->len;
4096     data = item->data;
4097     octet = *data++;
4098     negative = octet & 0x80;
4099 
4100     if (negative) {
4101         if ((l = PyLong_FromLong(-1)) == NULL) {
4102             goto error;
4103         }
4104     } else {
4105         if ((l = PyLong_FromLong(0)) == NULL) {
4106             goto error;
4107         }
4108     }
4109 
4110     if ((eight = PyLong_FromLong(8)) == NULL) {
4111         return NULL;
4112     }
4113 
4114     while (1) {
4115         if ((new_bits = PyLong_FromLong(octet)) == NULL) {
4116             goto error;
4117         }
4118 
4119         if ((tmp = PyNumber_Lshift(l, eight)) == NULL) {
4120             goto error;
4121         }
4122 
4123         Py_CLEAR(l);
4124 
4125         if ((l = PyNumber_Or(tmp, new_bits)) == NULL) {
4126             goto error;
4127         }
4128 
4129         Py_CLEAR(tmp);
4130         Py_CLEAR(new_bits);
4131 
4132         if (--len) {
4133             octet = *data++;
4134         } else {
4135             goto exit;
4136         }
4137     }
4138 
4139  error:
4140     Py_CLEAR(l);
4141  exit:
4142     Py_XDECREF(eight);
4143     Py_XDECREF(new_bits);
4144     Py_XDECREF(tmp);
4145     return l;
4146 }
4147 #if 0
4148 The following can be used to test integer_secitem_to_pylong()
4149 #define ASN1_TEST(octets, expect)                                       \
4150 {                                                                       \
4151         SECItem item;                                                   \
4152         PyObject *py_long = NULL;                                       \
4153         PyObject *py_str = NULL;                                        \
4154                                                                         \
4155         item.len = sizeof(octets);                                      \
4156         item.data = octets;                                             \
4157                                                                         \
4158         py_long = integer_secitem_to_pylong(&item);                     \
4159         py_str = PyObject_String(py_long);                              \
4160         printf("expect %8s got %8s\n", expect,                          \
4161                PyBytes_AsString(PyBaseString_UTF8(py_str, NULL)));      \
4162         Py_DECREF(py_long);                                             \
4163         Py_DECREF(py_str);                                              \
4164 }
4165 {
4166         unsigned char data1[] = {0x48};       /*     72 */
4167         unsigned char data2[] = {0x7F};       /*    127 */
4168         unsigned char data3[] = {0x80};       /*   -128 */
4169         unsigned char data4[] = {0x00, 0x80}; /*    128 */
4170         unsigned char data5[] = {0x96, 0x46}; /* -27066 */
4171 
4172         ASN1_TEST(data1, "72");
4173         ASN1_TEST(data2, "127");
4174         ASN1_TEST(data3, "-128");
4175         ASN1_TEST(data4, "128");
4176         ASN1_TEST(data5, "-27066");
4177 
4178     }
4179 #endif
4180 
4181 static PyObject *
integer_secitem_to_pystr(SECItem * item)4182 integer_secitem_to_pystr(SECItem *item)
4183 {
4184     PyObject *py_int = NULL;
4185     PyObject *py_str = NULL;
4186 
4187     if ((py_int = integer_secitem_to_pylong(item)) == NULL) {
4188         return NULL;
4189     }
4190 
4191     py_str = PyObject_String(py_int);
4192 
4193     Py_DECREF(py_int);
4194     return py_str;
4195 }
4196 
4197 static PyObject *
der_integer_secitem_to_pystr(SECItem * item)4198 der_integer_secitem_to_pystr(SECItem *item)
4199 {
4200     PyObject *py_str = NULL;
4201     SECItem tmp_item = *item;
4202 
4203     if (sec_strip_tag_and_length(&tmp_item) == SECSuccess)
4204 	py_str = integer_secitem_to_pystr(&tmp_item);
4205 
4206     return py_str;
4207 }
4208 
4209 static PyObject *
oid_secitem_to_pystr_desc(SECItem * oid)4210 oid_secitem_to_pystr_desc(SECItem *oid)
4211 {
4212     SECOidData *oiddata;
4213     char *oid_string = NULL;
4214     PyObject *py_oid_str = NULL;
4215 
4216     if ((oiddata = SECOID_FindOID(oid)) != NULL) {
4217 	return PyUnicode_FromString(oiddata->desc);
4218     }
4219     if ((oid_string = CERT_GetOidString(oid)) != NULL) {
4220         py_oid_str = PyUnicode_FromString(oid_string);
4221 	PR_smprintf_free(oid_string);
4222 	return py_oid_str;
4223     }
4224     return obj_to_hex((PyObject *)oid, 0, HEX_SEPARATOR_DEFAULT);
4225 }
4226 
4227 static PyObject *
oid_secitem_to_pyint_tag(SECItem * oid)4228 oid_secitem_to_pyint_tag(SECItem *oid)
4229 {
4230     SECOidTag oid_tag;
4231 
4232     oid_tag = SECOID_FindOIDTag(oid);
4233     return PyLong_FromLong(oid_tag);
4234 }
4235 
4236 static PyObject *
oid_secitem_to_pystr_dotted_decimal(SECItem * oid)4237 oid_secitem_to_pystr_dotted_decimal(SECItem *oid)
4238 {
4239     char *oid_string = NULL;
4240     PyObject *py_oid_string;
4241 
4242     if ((oid_string = CERT_GetOidString(oid)) == NULL) {
4243         return PyUnicode_FromString("");
4244     }
4245     if ((py_oid_string = PyUnicode_FromString(oid_string)) == NULL) {
4246         PR_smprintf_free(oid_string);
4247         return NULL;
4248     }
4249     PR_smprintf_free(oid_string);
4250     return py_oid_string;
4251 }
4252 
4253 static PyObject *
der_oid_secitem_to_pystr_desc(SECItem * item)4254 der_oid_secitem_to_pystr_desc(SECItem *item)
4255 {
4256     PyObject *str = NULL;
4257     SECItem tmp_item = *item;
4258 
4259     if (sec_strip_tag_and_length(&tmp_item) == SECSuccess)
4260 	str = oid_secitem_to_pystr_desc(&tmp_item);
4261 
4262     return str;
4263 }
4264 
4265 static PyObject *
der_utc_time_secitem_to_pystr(SECItem * item)4266 der_utc_time_secitem_to_pystr(SECItem *item)
4267 {
4268     PRTime pr_time = 0;
4269     PRExplodedTime exploded_time;
4270     char time_str[100];
4271 
4272     if ((DER_UTCTimeToTime(&pr_time, item) != SECSuccess)) {
4273         Py_RETURN_NONE;
4274     }
4275     PR_ExplodeTime(pr_time, PR_GMTParameters, &exploded_time);
4276     PR_FormatTime(time_str, sizeof(time_str), time_format, &exploded_time);
4277 
4278     return PyUnicode_FromString(time_str);
4279 }
4280 
4281 
4282 static PyObject *
der_generalized_time_secitem_to_pystr(SECItem * item)4283 der_generalized_time_secitem_to_pystr(SECItem *item)
4284 {
4285     PRTime pr_time = 0;
4286     PRExplodedTime exploded_time;
4287     char time_str[100];
4288 
4289     if ((DER_GeneralizedTimeToTime(&pr_time, item) != SECSuccess)) {
4290         Py_RETURN_NONE;
4291     }
4292     PR_ExplodeTime(pr_time, PR_GMTParameters, &exploded_time);
4293     PR_FormatTime(time_str, sizeof(time_str), time_format, &exploded_time);
4294 
4295     return PyUnicode_FromString(time_str);
4296 }
4297 
4298 
4299 static PRTime
time_choice_secitem_to_prtime(SECItem * item)4300 time_choice_secitem_to_prtime(SECItem *item)
4301 {
4302     PRTime pr_time = 0;
4303 
4304     switch (item->type) {
4305     case siUTCTime:
4306         DER_UTCTimeToTime(&pr_time, item);
4307         break;
4308     case siGeneralizedTime:
4309         DER_GeneralizedTimeToTime(&pr_time, item);
4310         break;
4311     default:
4312         PyErr_SetString(PyExc_ValueError, "unknown sec ANS.1 time type");
4313     }
4314     return pr_time;
4315 }
4316 
4317 static PyObject *
time_choice_secitem_to_pystr(SECItem * item)4318 time_choice_secitem_to_pystr(SECItem *item)
4319 {
4320     PRTime pr_time = 0;
4321     PRExplodedTime exploded_time;
4322     char time_str[100];
4323 
4324     pr_time = time_choice_secitem_to_prtime(item);
4325     PR_ExplodeTime(pr_time, PR_GMTParameters, &exploded_time);
4326     PR_FormatTime(time_str, sizeof(time_str), time_format, &exploded_time);
4327 
4328     return PyUnicode_FromString(time_str);
4329 }
4330 
4331 static PyObject *
der_octet_secitem_to_pystr(SECItem * item,int octets_per_line,char * separator)4332 der_octet_secitem_to_pystr(SECItem *item, int octets_per_line, char *separator)
4333 {
4334     PyObject *str = NULL;
4335     SECItem tmp_item = *item;
4336 
4337     if (sec_strip_tag_and_length(&tmp_item) == SECSuccess)
4338         str = raw_data_to_hex(tmp_item.data, tmp_item.len, octets_per_line, separator);
4339 
4340     return str;
4341 }
4342 
4343 static PyObject *
der_bit_string_secitem_to_pystr(SECItem * item)4344 der_bit_string_secitem_to_pystr(SECItem *item)
4345 {
4346     PyObject *str = NULL;
4347     SECItem tmp_item = *item;
4348     int unused_bits;
4349 
4350     if (sec_strip_tag_and_length(&tmp_item) != SECSuccess || tmp_item.len < 2) {
4351         Py_RETURN_NONE;
4352     }
4353 
4354     unused_bits = *tmp_item.data++;
4355     tmp_item.len--;
4356 
4357     str = raw_data_to_hex(tmp_item.data, tmp_item.len, 0, HEX_SEPARATOR_DEFAULT);
4358 
4359     if (unused_bits) {
4360 	PyUnicode_ConcatAndDel(&str, PyUnicode_FromFormat("(%d least significant bits unused)", unused_bits));
4361     }
4362 
4363     return str;
4364 }
4365 
4366 static PyObject *
ascii_string_secitem_to_escaped_ascii_pystr(SECItem * item)4367 ascii_string_secitem_to_escaped_ascii_pystr(SECItem *item)
4368 {
4369     PyObject *py_str = NULL;
4370     size_t escaped_len;
4371     const unsigned char *s; /* must be unsigned for table indexing to work */
4372     char *escaped_str, *dst, *src;
4373     AsciiEscapes *encode;
4374     unsigned int len;
4375     PyObject *result = NULL;
4376 
4377     escaped_len = ascii_encoded_strnlen((const char *)item->data, item->len);
4378 
4379     if ((py_str = PyBytes_FromStringAndSize(NULL, escaped_len)) == NULL) {
4380         return NULL;
4381     }
4382 
4383     escaped_str = PyBytes_AS_STRING(py_str);
4384 
4385     for (s = (unsigned char *)item->data, len = item->len, dst = escaped_str;
4386          len;
4387          s++, len--) {
4388         encode = &ascii_encoding_table[*s];
4389         for (src = encode->encoded; *src; src++) {
4390             *dst++ = *src;
4391         }
4392     }
4393 
4394     *dst = 0;
4395 
4396     result = PyUnicode_FromString(escaped_str);
4397     Py_DECREF(py_str);
4398     return result;
4399 }
4400 
4401 static PyObject *
der_ascii_string_secitem_to_escaped_ascii_pystr(SECItem * item)4402 der_ascii_string_secitem_to_escaped_ascii_pystr(SECItem *item)
4403 {
4404     SECItem tmp_item = *item;
4405 
4406     if (sec_strip_tag_and_length(&tmp_item) != SECSuccess) {
4407         PyErr_SetString(PyExc_ValueError, "malformed raw ascii string buffer");
4408         return NULL;
4409     }
4410 
4411     return ascii_string_secitem_to_escaped_ascii_pystr(&tmp_item);
4412 }
4413 
4414 static PyObject *
der_utf8_string_secitem_to_pyunicode(SECItem * item)4415 der_utf8_string_secitem_to_pyunicode(SECItem *item)
4416 {
4417     SECItem tmp_item = *item;
4418 
4419     if (sec_strip_tag_and_length(&tmp_item) != SECSuccess) {
4420         PyErr_SetString(PyExc_ValueError, "malformed raw ASN.1 BMP string buffer");
4421         return NULL;
4422     }
4423 
4424     return PyUnicode_DecodeUTF8((const char *)tmp_item.data, tmp_item.len, NULL);
4425 }
4426 
4427 
4428 static PyObject *
der_bmp_string_secitem_to_pyunicode(SECItem * item)4429 der_bmp_string_secitem_to_pyunicode(SECItem *item)
4430 {
4431     SECItem tmp_item = *item;
4432     int byte_order = 1;         /* 1 = big endian, asn.1 DER is always big endian */
4433 
4434     if (sec_strip_tag_and_length(&tmp_item) != SECSuccess) {
4435         PyErr_SetString(PyExc_ValueError, "malformed raw ASN.1 BMP string buffer");
4436         return NULL;
4437     }
4438 
4439     if (tmp_item.len % 2) {
4440         PyErr_SetString(PyExc_ValueError, "raw ASN.1 BMP string length must be multiple of 2");
4441         return NULL;
4442     }
4443 
4444     return PyUnicode_DecodeUTF16((const char *)tmp_item.data, tmp_item.len,
4445                                  NULL, &byte_order);
4446 }
4447 
4448 
4449 static PyObject *
der_universal_string_secitem_to_pyunicode(SECItem * item)4450 der_universal_string_secitem_to_pyunicode(SECItem *item)
4451 {
4452     SECItem tmp_item = *item;
4453     int byte_order = 1;         /* 1 = big endian, asn.1 DER is always big endian */
4454 
4455     if (sec_strip_tag_and_length(&tmp_item) != SECSuccess) {
4456         PyErr_SetString(PyExc_ValueError, "malformed raw ASN.1 Universal string buffer");
4457         return NULL;
4458     }
4459 
4460     if (tmp_item.len % 4) {
4461         PyErr_SetString(PyExc_ValueError, "raw ASN.1 Universal string length must be multiple of 4");
4462         return NULL;
4463     }
4464 
4465     return PyUnicode_DecodeUTF32((const char *)tmp_item.data, tmp_item.len,
4466                                  NULL, &byte_order);
4467 }
4468 
4469 static PyObject *
der_universal_secitem_to_pystr(SECItem * item)4470 der_universal_secitem_to_pystr(SECItem *item)
4471 {
4472     switch (item->data[0] & SEC_ASN1_TAGNUM_MASK) {
4473     case SEC_ASN1_ENUMERATED:
4474     case SEC_ASN1_INTEGER:
4475         return der_integer_secitem_to_pystr(item);
4476     case SEC_ASN1_OBJECT_ID:
4477         return der_oid_secitem_to_pystr_desc(item);
4478     case SEC_ASN1_BOOLEAN:
4479         return der_boolean_secitem_to_pystr(item);
4480     case SEC_ASN1_UTF8_STRING:
4481         return der_utf8_string_secitem_to_pyunicode(item);
4482     case SEC_ASN1_PRINTABLE_STRING:
4483     case SEC_ASN1_VISIBLE_STRING:
4484     case SEC_ASN1_IA5_STRING:
4485     case SEC_ASN1_T61_STRING:
4486         return der_ascii_string_secitem_to_escaped_ascii_pystr(item);
4487     case SEC_ASN1_GENERALIZED_TIME:
4488         return der_generalized_time_secitem_to_pystr(item);
4489     case SEC_ASN1_UTC_TIME:
4490         return der_utc_time_secitem_to_pystr(item);
4491     case SEC_ASN1_NULL:
4492         return PyUnicode_FromString("(null)");
4493     case SEC_ASN1_SET:
4494     case SEC_ASN1_SEQUENCE:
4495         return der_set_or_str_secitem_to_pylist_of_pystr(item);
4496     case SEC_ASN1_OCTET_STRING:
4497         return der_octet_secitem_to_pystr(item, 0, HEX_SEPARATOR_DEFAULT);
4498     case SEC_ASN1_BIT_STRING:
4499         der_bit_string_secitem_to_pystr(item);
4500         break;
4501     case SEC_ASN1_BMP_STRING:
4502         return der_bmp_string_secitem_to_pyunicode(item);
4503     case SEC_ASN1_UNIVERSAL_STRING:
4504         return der_universal_string_secitem_to_pyunicode(item);
4505     default:
4506         return raw_data_to_hex(item->data, item->len, 0, HEX_SEPARATOR_DEFAULT);
4507     }
4508     Py_RETURN_NONE;
4509 }
4510 
4511 PyDoc_STRVAR(cert_der_universal_secitem_fmt_lines_doc,
4512 "der_universal_secitem_fmt_lines(sec_item, level=0, octets_per_line=0, separator=':') -> list of (indent, string) tuples\n\
4513 \n\
4514 :Parameters:\n\
4515     sec_item : SecItem object\n\
4516         A SecItem containing a DER encoded ASN1 universal type\n\
4517     level : integer\n\
4518         Initial indentation level, all subsequent indents are relative\n\
4519         to this starting level.\n\
4520     octets_per_line : integer\n\
4521         Number of octets formatted on one line, if 0 then\n\
4522         return a single string instead of an array of lines\n\
4523     separator : string\n\
4524         String used to seperate each octet\n\
4525         If None it will be as if the empty string had been\n\
4526         passed and no separator will be used.\n\
4527 \n\
4528 Given a SecItem in DER format which encodes a ASN.1 universal\n\
4529 type convert the item to a string and return a list of\n\
4530 (indent, string) tuples.\n\
4531 ");
4532 static PyObject *
cert_der_universal_secitem_fmt_lines(PyObject * self,PyObject * args,PyObject * kwds)4533 cert_der_universal_secitem_fmt_lines(PyObject *self, PyObject *args, PyObject *kwds)
4534 {
4535     static char *kwlist[] = {"level", "octets_per_line", "separator", NULL};
4536     SecItem *py_sec_item = NULL;
4537     int level = 0;
4538     int octets_per_line = OCTETS_PER_LINE_DEFAULT;
4539     char *hex_separator = HEX_SEPARATOR_DEFAULT;
4540     PyObject *lines = NULL;
4541     PyObject *obj = NULL;
4542     SECItem *item = NULL;
4543 
4544     TraceMethodEnter(self);
4545 
4546     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|iiz:der_universal_secitem_fmt_lines", kwlist,
4547                                      &SecItemType, &py_sec_item,
4548                                      &level, &octets_per_line, &hex_separator))
4549         return NULL;
4550 
4551     item = &py_sec_item->item;
4552 
4553     if ((lines = PyList_New(0)) == NULL) {
4554         return NULL;
4555     }
4556 
4557     switch (item->data[0] & SEC_ASN1_TAGNUM_MASK) {
4558     case SEC_ASN1_ENUMERATED:
4559     case SEC_ASN1_INTEGER:
4560         obj = der_integer_secitem_to_pystr(item);
4561         break;
4562     case SEC_ASN1_OBJECT_ID:
4563         obj = der_oid_secitem_to_pystr_desc(item);
4564         break;
4565     case SEC_ASN1_BOOLEAN:
4566         obj = der_boolean_secitem_to_pystr(item);
4567         break;
4568     case SEC_ASN1_UTF8_STRING:
4569         obj = der_utf8_string_secitem_to_pyunicode(item);
4570         break;
4571     case SEC_ASN1_PRINTABLE_STRING:
4572     case SEC_ASN1_VISIBLE_STRING:
4573     case SEC_ASN1_IA5_STRING:
4574     case SEC_ASN1_T61_STRING:
4575         obj = der_ascii_string_secitem_to_escaped_ascii_pystr(item);
4576         break;
4577     case SEC_ASN1_GENERALIZED_TIME:
4578         obj = der_generalized_time_secitem_to_pystr(item);
4579         break;
4580     case SEC_ASN1_UTC_TIME:
4581         obj = der_utc_time_secitem_to_pystr(item);
4582         break;
4583     case SEC_ASN1_NULL:
4584         obj = PyUnicode_FromString("(null)");
4585         break;
4586     case SEC_ASN1_SET:
4587     case SEC_ASN1_SEQUENCE:
4588         obj = der_set_or_str_secitem_to_pylist_of_pystr(item);
4589         break;
4590     case SEC_ASN1_OCTET_STRING:
4591         obj = der_octet_secitem_to_pystr(item, octets_per_line, hex_separator);
4592         break;
4593     case SEC_ASN1_BIT_STRING:
4594         der_bit_string_secitem_to_pystr(item);
4595         break;
4596     case SEC_ASN1_BMP_STRING:
4597         obj = der_bmp_string_secitem_to_pyunicode(item);
4598         break;
4599     case SEC_ASN1_UNIVERSAL_STRING:
4600         obj = der_universal_string_secitem_to_pyunicode(item);
4601         break;
4602     default:
4603         obj = raw_data_to_hex(item->data, item->len, octets_per_line, hex_separator);
4604         break;
4605     }
4606 
4607     if (obj) {
4608         if (PyList_Check(obj)) {
4609             APPEND_LINES_AND_CLEAR(lines, obj, level, fail);
4610         } else {
4611             FMT_OBJ_AND_APPEND(lines, NULL, obj, level, fail);
4612         }
4613     }
4614 
4615     return lines;
4616 
4617  fail:
4618     Py_XDECREF(lines);
4619     return NULL;
4620 }
4621 
4622 static PyObject *
secitem_integer_format_lines(SECItem * item,int level)4623 secitem_integer_format_lines(SECItem *item, int level)
4624 {
4625     PyObject *lines = NULL;
4626     PyObject *obj = NULL;
4627     PyObject *obj1 = NULL;
4628     PyObject *obj_lines = NULL;
4629 
4630     TraceMethodEnter(NULL);
4631 
4632     if ((lines = PyList_New(0)) == NULL) {
4633         return NULL;
4634     }
4635 
4636     if (item->len > 8) {
4637         if ((obj_lines = SECItem_to_hex(item, OCTETS_PER_LINE_DEFAULT, HEX_SEPARATOR_DEFAULT)) == NULL) {
4638             goto fail;
4639         }
4640         APPEND_LINES_AND_CLEAR(lines, obj_lines, level, fail);
4641     } else {
4642         if ((obj = integer_secitem_to_pylong(item)) == NULL) {
4643             goto fail;
4644         }
4645         if ((obj1 = obj_sprintf("%d (%#x)", obj, obj)) == NULL) {
4646             goto fail;
4647         }
4648         Py_CLEAR(obj);
4649         FMT_OBJ_AND_APPEND(lines, NULL, obj1, level, fail);
4650         Py_CLEAR(obj1);
4651     }
4652 
4653     return lines;
4654 
4655  fail:
4656     Py_XDECREF(obj_lines);
4657     Py_XDECREF(obj);
4658     Py_XDECREF(obj1);
4659     Py_XDECREF(lines);
4660     return NULL;
4661 }
4662 
4663 static PyObject *
fingerprint_format_lines(SECItem * item,int level)4664 fingerprint_format_lines(SECItem *item, int level)
4665 {
4666     PyObject *lines = NULL;
4667     PyObject *obj = NULL;
4668 
4669     TraceMethodEnter(NULL);
4670 
4671     if ((lines = PyList_New(0)) == NULL) {
4672         return NULL;
4673     }
4674 
4675     FMT_LABEL_AND_APPEND(lines, _("Fingerprint (MD5)"), level, fail);
4676     if ((obj = PyBytes_FromStringAndSize(NULL, MD5_LENGTH)) == NULL) {
4677         goto fail;
4678     }
4679     if (PK11_HashBuf(SEC_OID_MD5, (unsigned char *)PyBytes_AsString(obj),
4680                      item->data, item->len) != SECSuccess) {
4681         set_nspr_error(NULL);
4682     }
4683     APPEND_OBJ_TO_HEX_LINES_AND_CLEAR(lines, obj, level+1, fail);
4684 
4685     FMT_LABEL_AND_APPEND(lines, _("Fingerprint (SHA1)"), level, fail);
4686     if ((obj = PyBytes_FromStringAndSize(NULL, SHA1_LENGTH)) == NULL) {
4687         goto fail;
4688     }
4689     if (PK11_HashBuf(SEC_OID_SHA1, (unsigned char *)PyBytes_AsString(obj),
4690                      item->data, item->len) != SECSuccess) {
4691         set_nspr_error(NULL);
4692     }
4693     APPEND_OBJ_TO_HEX_LINES_AND_CLEAR(lines, obj, level+1, fail);
4694 
4695     return lines;
4696 
4697  fail:
4698     Py_XDECREF(obj);
4699     Py_XDECREF(lines);
4700     return NULL;
4701 }
4702 
4703 static PyObject *
CERTGeneralName_type_string_to_pystr(CERTGeneralName * general_name)4704 CERTGeneralName_type_string_to_pystr(CERTGeneralName *general_name)
4705 {
4706 
4707     switch(general_name->type) {
4708     case certOtherName: {
4709         PyObject *py_oid = oid_secitem_to_pystr_desc(&general_name->name.OthName.oid);
4710         if (py_oid) {
4711             PyObject *result = PyUnicode_FromFormat(_("Other Name (%U)"), py_oid);
4712             Py_DECREF(py_oid);
4713             return result;
4714         } else {
4715             return PyUnicode_FromString(_("Other Name"));
4716         }
4717     }
4718     case certRFC822Name:
4719         return PyUnicode_FromString(_("RFC822 Name"));
4720     case certDNSName:
4721         return PyUnicode_FromString(_("DNS name"));
4722     case certX400Address:
4723         return PyUnicode_FromString(_("X400 Address"));
4724     case certDirectoryName:
4725         return PyUnicode_FromString(_("Directory Name"));
4726     case certEDIPartyName:
4727         return PyUnicode_FromString(_("EDI Party"));
4728     case certURI:
4729         return PyUnicode_FromString(_("URI"));
4730     case certIPAddress:
4731         return PyUnicode_FromString(_("IP Address"));
4732     case certRegisterID:
4733         return PyUnicode_FromString(_("Registered ID"));
4734     default:
4735 	return PyUnicode_FromFormat(_("unknown type [%d]"), (int)general_name->type - 1);
4736     }
4737 }
4738 
4739 static PyObject *
CERTGeneralName_to_pystr(CERTGeneralName * general_name)4740 CERTGeneralName_to_pystr(CERTGeneralName *general_name)
4741 {
4742     switch(general_name->type) {
4743     case certOtherName:
4744         return der_any_secitem_to_pystr(&general_name->name.OthName.name);
4745     case certRFC822Name:
4746         return ascii_string_secitem_to_escaped_ascii_pystr(&general_name->name.other);
4747     case certDNSName:
4748         return ascii_string_secitem_to_escaped_ascii_pystr(&general_name->name.other);
4749     case certX400Address:
4750         return der_any_secitem_to_pystr(&general_name->name.other);
4751     case certDirectoryName:
4752         return CERTName_to_pystr(&general_name->name.directoryName);
4753     case certEDIPartyName:
4754         return der_any_secitem_to_pystr(&general_name->name.other);
4755     case certURI:
4756         return ascii_string_secitem_to_escaped_ascii_pystr(&general_name->name.other);
4757     case certIPAddress:
4758         return ip_addr_secitem_to_pystr(&general_name->name.other);
4759     case certRegisterID:
4760         return oid_secitem_to_pystr_desc(&general_name->name.other);
4761     default:
4762         PyErr_Format(PyExc_ValueError, _("unknown type [%d]"), (int)general_name->type - 1);
4763         return NULL;
4764 
4765     }
4766 }
4767 
4768 static PyObject *
CERTGeneralName_to_pystr_with_label(CERTGeneralName * general_name)4769 CERTGeneralName_to_pystr_with_label(CERTGeneralName *general_name)
4770 {
4771     PyObject *py_label = NULL;
4772     PyObject *py_value = NULL;
4773     PyObject *result = NULL;
4774 
4775     if (!general_name) {
4776         return NULL;
4777     }
4778 
4779     py_label = CERTGeneralName_type_string_to_pystr(general_name);
4780     py_value = CERTGeneralName_to_pystr(general_name);
4781 
4782     if (py_label && py_value) {
4783         result = PyUnicode_FromFormat("%U: %U", py_label, py_value);
4784     } else if (py_value) {
4785         Py_INCREF(py_value);
4786         result = py_value;
4787     }
4788 
4789     Py_XDECREF(py_label);
4790     Py_XDECREF(py_value);
4791 
4792     return result;
4793 }
4794 
4795 static PyObject *
CERTAVA_value_to_pystr(CERTAVA * ava)4796 CERTAVA_value_to_pystr(CERTAVA *ava)
4797 {
4798     PyObject *result = NULL;
4799     SECOidTag oid_tag;
4800     const char *attr_name;
4801     char *oid_name;
4802     char value_buf[1024];
4803     SECItem *value_item;
4804 
4805     if (!ava) {
4806         return PyUnicode_FromString("");
4807     }
4808 
4809     value_buf[0] = 0;
4810     attr_name = NULL;
4811     oid_name = NULL;
4812 
4813     /*
4814      * Get the AVA's attribute name (e.g. type) as a string.  If we
4815      * can't get the canonical name use a dotted-decimal OID
4816      * representation instead.
4817      */
4818     if ((oid_tag = CERT_GetAVATag(ava)) != -1) {
4819         attr_name = ava_oid_tag_to_name(oid_tag);
4820     }
4821 
4822     if (attr_name == NULL) {
4823         if ((oid_name = CERT_GetOidString(&ava->type)) == NULL) {
4824             return set_nspr_error("cannot convert AVA type to OID string");
4825         }
4826     }
4827 
4828     /* Get the AVA's attribute value as a string */
4829     if ((value_item = CERT_DecodeAVAValue(&ava->value)) == NULL) {
4830         if (oid_name) PR_smprintf_free(oid_name);
4831         return set_nspr_error("unable to decode AVA value");
4832     }
4833     if (CERT_RFC1485_EscapeAndQuote(value_buf, sizeof(value_buf),
4834                                     (char *)value_item->data,
4835                                     value_item->len) != SECSuccess) {
4836         if (oid_name) PR_smprintf_free(oid_name);
4837         SECITEM_FreeItem(value_item, PR_TRUE);
4838         return set_nspr_error("unable to escape AVA value string");
4839     }
4840     SECITEM_FreeItem(value_item, PR_TRUE);
4841 
4842     /* Format "name=value" */
4843     if ((result = PyUnicode_FromFormat("%s=%s",
4844                                        attr_name ? attr_name : oid_name,
4845                                        value_buf)) == NULL) {
4846         if (oid_name) PR_smprintf_free(oid_name);
4847         return NULL;
4848     }
4849 
4850     if (oid_name) PR_smprintf_free(oid_name);
4851 
4852     return result;
4853 }
4854 
4855 static PyObject *
CERTRDN_to_pystr(CERTRDN * rdn)4856 CERTRDN_to_pystr(CERTRDN *rdn)
4857 {
4858     PyObject *result = NULL;
4859     CERTAVA **avas, *ava;
4860     SECOidTag oid_tag;
4861     const char *attr_name;
4862     char *oid_name;
4863     bool first;
4864     char value_buf[1024];
4865     SECItem *value_item;
4866 
4867     if (!rdn || !(avas = rdn->avas) || *avas == NULL) {
4868         return PyUnicode_FromString("");
4869     }
4870 
4871     first = true;
4872     while ((ava = *avas++) != NULL) {
4873         value_buf[0] = 0;
4874         attr_name = NULL;
4875         oid_name = NULL;
4876 
4877         /*
4878          * Get the AVA's attribute name (e.g. type) as a string.  If we
4879          * can't get the canonical name use a dotted-decimal OID
4880          * representation instead.
4881          */
4882         if ((oid_tag = CERT_GetAVATag(ava)) != -1) {
4883             attr_name = ava_oid_tag_to_name(oid_tag);
4884         }
4885 
4886         if (attr_name == NULL) {
4887             if ((oid_name = CERT_GetOidString(&ava->type)) == NULL) {
4888                 return set_nspr_error("cannot convert AVA type to OID string");
4889             }
4890         }
4891 
4892         /* Get the AVA's attribute value as a string */
4893         if ((value_item = CERT_DecodeAVAValue(&ava->value)) == NULL) {
4894             if (oid_name) PR_smprintf_free(oid_name);
4895             return set_nspr_error("unable to decode AVA value");
4896         }
4897         if (CERT_RFC1485_EscapeAndQuote(value_buf, sizeof(value_buf),
4898                                         (char *)value_item->data,
4899                                         value_item->len) != SECSuccess) {
4900             if (oid_name) PR_smprintf_free(oid_name);
4901             SECITEM_FreeItem(value_item, PR_TRUE);
4902             return set_nspr_error("unable to escape AVA value string");
4903         }
4904         SECITEM_FreeItem(value_item, PR_TRUE);
4905 
4906         /*
4907          * Format "name=value", if there is more than one AVA join them
4908          * together with a "+". Typically there is only one AVA.
4909          */
4910         if (first) {
4911             if ((result = PyUnicode_FromFormat("%s=%s",
4912                                                attr_name ? attr_name : oid_name,
4913                                                value_buf)) == NULL) {
4914                 if (oid_name) PR_smprintf_free(oid_name);
4915                 return NULL;
4916             }
4917         } else {
4918             PyObject *temp;
4919 
4920             if ((temp = PyUnicode_FromFormat("+%s=%s",
4921                                              attr_name ? attr_name : oid_name,
4922                                              value_buf)) == NULL) {
4923                 if (oid_name) PR_smprintf_free(oid_name);
4924                 return NULL;
4925             }
4926             PyUnicode_ConcatAndDel(&result, temp);
4927             if (result == NULL) {
4928                 if (oid_name) PR_smprintf_free(oid_name);
4929                 return NULL;
4930             }
4931         }
4932 
4933         if (oid_name) PR_smprintf_free(oid_name);
4934         first = false;
4935     }
4936     return result;
4937 }
4938 
4939 static PyObject *
cert_trust_flags(unsigned int flags,RepresentationKind repr_kind)4940 cert_trust_flags(unsigned int flags, RepresentationKind repr_kind)
4941 {
4942     BIT_FLAGS_TO_LIST_PROLOGUE();
4943 
4944 #if (NSS_VMAJOR > 3) || (NSS_VMAJOR == 3 && NSS_VMINOR >= 13)
4945     BIT_FLAGS_TO_LIST(CERTDB_TERMINAL_RECORD,   _("Terminal Record"));
4946 #else
4947     BIT_FLAGS_TO_LIST(CERTDB_VALID_PEER,        _("Valid Peer"));
4948 #endif
4949     BIT_FLAGS_TO_LIST(CERTDB_TRUSTED,           _("Trusted"));
4950     BIT_FLAGS_TO_LIST(CERTDB_SEND_WARN,         _("Warn When Sending"));
4951     BIT_FLAGS_TO_LIST(CERTDB_VALID_CA,          _("Valid CA"));
4952     BIT_FLAGS_TO_LIST(CERTDB_TRUSTED_CA,        _("Trusted CA"));
4953     BIT_FLAGS_TO_LIST(CERTDB_NS_TRUSTED_CA,     _("Netscape Trusted CA"));
4954     BIT_FLAGS_TO_LIST(CERTDB_USER,              _("User"));
4955     BIT_FLAGS_TO_LIST(CERTDB_TRUSTED_CLIENT_CA, _("Trusted Client CA"));
4956     BIT_FLAGS_TO_LIST(CERTDB_GOVT_APPROVED_CA,  _("Step-up"));
4957 
4958     BIT_FLAGS_TO_LIST_EPILOGUE();
4959 }
4960 
4961 static PyObject *
cert_usage_flags(unsigned int flags,RepresentationKind repr_kind)4962 cert_usage_flags(unsigned int flags, RepresentationKind repr_kind)
4963 {
4964     BIT_FLAGS_TO_LIST_PROLOGUE();
4965 
4966     BIT_FLAGS_TO_LIST(certificateUsageSSLClient,             _("SSL Client"));
4967     BIT_FLAGS_TO_LIST(certificateUsageSSLServer,             _("SSL Server"));
4968     BIT_FLAGS_TO_LIST(certificateUsageSSLServerWithStepUp,   _("SSL Server With StepUp"));
4969     BIT_FLAGS_TO_LIST(certificateUsageSSLCA,                 _("SSL CA"));
4970     BIT_FLAGS_TO_LIST(certificateUsageEmailSigner,           _("Email Signer"));
4971     BIT_FLAGS_TO_LIST(certificateUsageEmailRecipient,        _("Email Recipient"));
4972     BIT_FLAGS_TO_LIST(certificateUsageObjectSigner,          _("Object Signer"));
4973     BIT_FLAGS_TO_LIST(certificateUsageUserCertImport,        _("User Certificate Import"));
4974     BIT_FLAGS_TO_LIST(certificateUsageVerifyCA,              _("Verify CA"));
4975     BIT_FLAGS_TO_LIST(certificateUsageProtectedObjectSigner, _("Protected Object Signer"));
4976     BIT_FLAGS_TO_LIST(certificateUsageStatusResponder,       _("Status Responder"));
4977     BIT_FLAGS_TO_LIST(certificateUsageAnyCA,                 _("Any CA"));
4978 
4979     BIT_FLAGS_TO_LIST_EPILOGUE();
4980 }
4981 
4982 static PyObject *
key_usage_flags(unsigned int flags,RepresentationKind repr_kind)4983 key_usage_flags(unsigned int flags, RepresentationKind repr_kind)
4984 {
4985     BIT_FLAGS_TO_LIST_PROLOGUE();
4986 
4987     BIT_FLAGS_TO_LIST(KU_DIGITAL_SIGNATURE, _("Digital Signature"));
4988     BIT_FLAGS_TO_LIST(KU_NON_REPUDIATION,   _("Non-Repudiation"));
4989     BIT_FLAGS_TO_LIST(KU_KEY_ENCIPHERMENT,  _("Key Encipherment"));
4990     BIT_FLAGS_TO_LIST(KU_DATA_ENCIPHERMENT, _("Data Encipherment"));
4991     BIT_FLAGS_TO_LIST(KU_KEY_AGREEMENT,     _("Key Agreement"));
4992     BIT_FLAGS_TO_LIST(KU_KEY_CERT_SIGN,     _("Certificate Signing"));
4993     BIT_FLAGS_TO_LIST(KU_CRL_SIGN,          _("CRL Signing"));
4994     BIT_FLAGS_TO_LIST(KU_ENCIPHER_ONLY,     _("Encipher Only"));
4995 #ifdef KU_DECIPHER_ONLY
4996     BIT_FLAGS_TO_LIST(KU_DECIPHER_ONLY,     _("Decipher Only"));
4997 #endif
4998     /*
4999      * The following flags are not present in certs but appear in
5000      * CERTVerifyNode when the error is
5001      * SEC_ERROR_INADEQUATE_KEY_USAGE. This rountine is also used
5002      * to print those flags.
5003      */
5004     BIT_FLAGS_TO_LIST(KU_DIGITAL_SIGNATURE_OR_NON_REPUDIATION, _("Digital Signature or Non-Repudiation"));
5005     BIT_FLAGS_TO_LIST(KU_KEY_AGREEMENT_OR_ENCIPHERMENT,        _("Key Agreement or Data Encipherment"));
5006     BIT_FLAGS_TO_LIST(KU_NS_GOVT_APPROVED,                     _("Government Approved"));
5007 
5008     BIT_FLAGS_TO_LIST_EPILOGUE();
5009 }
5010 
5011 static PyObject *
cert_type_flags(unsigned int flags,RepresentationKind repr_kind)5012 cert_type_flags(unsigned int flags, RepresentationKind repr_kind)
5013 {
5014     BIT_FLAGS_TO_LIST_PROLOGUE();
5015 
5016     BIT_FLAGS_TO_LIST(NS_CERT_TYPE_SSL_CLIENT,        _("SSL Client"));
5017     BIT_FLAGS_TO_LIST(NS_CERT_TYPE_SSL_SERVER,        _("SSL Server"));
5018     BIT_FLAGS_TO_LIST(NS_CERT_TYPE_EMAIL,             _("Email"));
5019     BIT_FLAGS_TO_LIST(NS_CERT_TYPE_OBJECT_SIGNING,    _("Object Signing"));
5020     BIT_FLAGS_TO_LIST(NS_CERT_TYPE_RESERVED,          _("Reserved"));
5021     BIT_FLAGS_TO_LIST(NS_CERT_TYPE_SSL_CA,            _("SSL CA"));
5022     BIT_FLAGS_TO_LIST(NS_CERT_TYPE_EMAIL_CA,          _("Email CA"));
5023     BIT_FLAGS_TO_LIST(NS_CERT_TYPE_OBJECT_SIGNING_CA, _("Object Signing CA"));
5024     /*
5025      * The following flags are not actual cert types but they get
5026      * OR'ed into a cert type bitmask.
5027      */
5028    BIT_FLAGS_TO_LIST(EXT_KEY_USAGE_TIME_STAMP,        _("Key Usage Timestamp"));
5029    BIT_FLAGS_TO_LIST(EXT_KEY_USAGE_STATUS_RESPONDER,  _("Key Usage Status Responder"));
5030 
5031    BIT_FLAGS_TO_LIST_EPILOGUE();
5032 }
5033 
5034 static PyObject *
nss_init_flags(unsigned int flags,RepresentationKind repr_kind)5035 nss_init_flags(unsigned int flags, RepresentationKind repr_kind)
5036 {
5037     BIT_FLAGS_TO_LIST_PROLOGUE();
5038 
5039     BIT_FLAGS_TO_LIST(NSS_INIT_READONLY,       _("Read Only"));
5040     BIT_FLAGS_TO_LIST(NSS_INIT_NOCERTDB,       _("No Certificate Database"));
5041     BIT_FLAGS_TO_LIST(NSS_INIT_NOMODDB,        _("No Module Database"));
5042     BIT_FLAGS_TO_LIST(NSS_INIT_FORCEOPEN,      _("Force Open"));
5043     BIT_FLAGS_TO_LIST(NSS_INIT_NOROOTINIT,     _("No Root Init"));
5044     BIT_FLAGS_TO_LIST(NSS_INIT_OPTIMIZESPACE,  _("Optimize Space"));
5045     BIT_FLAGS_TO_LIST(NSS_INIT_PK11THREADSAFE, _("PK11 Thread Safe"));
5046     BIT_FLAGS_TO_LIST(NSS_INIT_PK11RELOAD,     _("PK11 Reload"));
5047     BIT_FLAGS_TO_LIST(NSS_INIT_NOPK11FINALIZE, _("No PK11 Finalize"));
5048     BIT_FLAGS_TO_LIST(NSS_INIT_RESERVED,       _("Reserved"));
5049 
5050     BIT_FLAGS_TO_LIST_EPILOGUE();
5051 }
5052 
5053 
5054 static PyObject *
ip_addr_secitem_to_pystr(SECItem * item)5055 ip_addr_secitem_to_pystr(SECItem *item)
5056 {
5057     PRNetAddr  addr;
5058     char buf[1024];
5059 
5060     memset(&addr, 0, sizeof(addr));
5061     if (item->len == 4) {
5062 	addr.inet.family = PR_AF_INET;
5063 	memcpy(&addr.inet.ip, item->data, item->len);
5064     } else if (item->len == 16) {
5065 	addr.ipv6.family = PR_AF_INET6;
5066 	memcpy(addr.ipv6.ip.pr_s6_addr, item->data, item->len);
5067 	if (PR_IsNetAddrType(&addr, PR_IpAddrV4Mapped)) {
5068 	    /* convert to IPv4.  */
5069 	    addr.inet.family = PR_AF_INET;
5070 	    memcpy(&addr.inet.ip, &addr.ipv6.ip.pr_s6_addr[12], 4);
5071 	    memset(&addr.inet.pad[0], 0, sizeof addr.inet.pad);
5072 	}
5073     } else {
5074         return secitem_to_pystr_hex(item);
5075     }
5076 
5077     if (PR_NetAddrToString(&addr, buf, sizeof(buf)) != PR_SUCCESS) {
5078         return secitem_to_pystr_hex(item);
5079     }
5080 
5081     return PyUnicode_FromString(buf);
5082 }
5083 
5084 static PyObject *
SECItem_to_hex(SECItem * item,int octets_per_line,char * separator)5085 SECItem_to_hex(SECItem *item, int octets_per_line, char *separator)
5086 {
5087     return raw_data_to_hex(item->data, item->len, octets_per_line, separator);
5088 }
5089 
5090 static PyObject *
SECItem_der_to_hex(SECItem * item,int octets_per_line,char * separator)5091 SECItem_der_to_hex(SECItem *item, int octets_per_line, char *separator)
5092 {
5093     SECItem tmp_item = *item;
5094 
5095     if (sec_strip_tag_and_length(&tmp_item) != SECSuccess) {
5096         PyErr_SetString(PyExc_ValueError, "malformed ASN.1 DER data");
5097         return NULL;
5098     }
5099 
5100     return raw_data_to_hex(tmp_item.data, tmp_item.len, octets_per_line, separator);
5101 }
5102 
5103 /* ========================================================================== */
5104 /* =============================== SecItem Class ============================ */
5105 /* ========================================================================== */
5106 
5107 /* ============================ Attribute Access ============================ */
5108 
5109 static PyObject *
SecItem_get_type(SecItem * self,void * closure)5110 SecItem_get_type(SecItem *self, void *closure)
5111 {
5112     TraceMethodEnter(self);
5113 
5114     return PyLong_FromLong(self->item.type);
5115 }
5116 
5117 static PyObject *
SecItem_get_len(SecItem * self,void * closure)5118 SecItem_get_len(SecItem *self, void *closure)
5119 {
5120     TraceMethodEnter(self);
5121 
5122     return PyLong_FromLong(self->item.len);
5123 }
5124 
5125 static PyObject *
SecItem_get_data(SecItem * self,void * closure)5126 SecItem_get_data(SecItem *self, void *closure)
5127 {
5128     TraceMethodEnter(self);
5129 
5130     return PyBytes_FromStringAndSize((const char *)self->item.data, self->item.len);
5131 }
5132 
5133 static
5134 PyGetSetDef SecItem_getseters[] = {
5135     {"type",       (getter)SecItem_get_type,    (setter)NULL,
5136      "the SecItem type (si* constant)", NULL},
5137     {"len",        (getter)SecItem_get_len,     (setter)NULL,
5138      "number of octets in SecItem buffer", NULL},
5139     {"data",       (getter)SecItem_get_data,    (setter)NULL,
5140      "contents of SecItem buffer", NULL},
5141     {NULL}  /* Sentinel */
5142 };
5143 
5144 static PyMemberDef SecItem_members[] = {
5145     {NULL}  /* Sentinel */
5146 };
5147 
5148 /* ============================== Class Methods ============================= */
5149 
5150 PyDoc_STRVAR(SecItem_get_oid_sequence_doc,
5151 "get_oid_sequence(repr_kind=AsString) -> (obj, ...)\n\
5152 \n\
5153 :Parameters:\n\
5154     repr_kind : RepresentationKind constant\n\
5155         Specifies what the contents of the returned tuple will be.\n\
5156         May be one of:\n\
5157 \n\
5158         AsObject\n\
5159             Each extended key usage will be a SecItem object embedding\n\
5160             the OID in DER format.\n\
5161         AsString\n\
5162             Each extended key usage will be a descriptive string.\n\
5163             (e.g. \"TLS Web Server Authentication Certificate\")\n\
5164         AsDottedDecimal\n\
5165             Each extended key usage will be OID rendered as a dotted decimal string.\n\
5166             (e.g. \"OID.1.3.6.1.5.5.7.3.1\")\n\
5167         AsEnum\n\
5168             Each extended key usage will be OID tag enumeration constant (int).\n\
5169             (e.g. nss.SEC_OID_EXT_KEY_USAGE_SERVER_AUTH)\n\
5170 \n\
5171 Return a tuple of OID's according the representation kind.\n\
5172 ");
5173 static PyObject *
SecItem_get_oid_sequence(SecItem * self,PyObject * args,PyObject * kwds)5174 SecItem_get_oid_sequence(SecItem *self, PyObject *args, PyObject *kwds)
5175 {
5176     static char *kwlist[] = {"repr_kind", NULL};
5177     int repr_kind = AsString;
5178 
5179     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:get_oid_sequence", kwlist,
5180                                      &repr_kind))
5181         return NULL;
5182 
5183     return decode_oid_sequence_to_tuple(&self->item, repr_kind);
5184 }
5185 
5186 PyDoc_STRVAR(SecItem_get_integer_doc,
5187 "get_integer() -> int or long\n\
5188 \n\
5189 If the SecItem contains an ASN.1 integer in DER format return\n\
5190 a Python integer (or long)\n\
5191 ");
5192 static PyObject *
SecItem_get_integer(SecItem * self,PyObject * args)5193 SecItem_get_integer(SecItem *self, PyObject *args)
5194 {
5195     return integer_secitem_to_pylong(&self->item);
5196 }
5197 
5198 PyDoc_STRVAR(SecItem_to_hex_doc,
5199 "to_hex(octets_per_line=0, separator=':') -> string or list of strings\n\
5200 \n\
5201 :Parameters:\n\
5202     octets_per_line : integer\n\
5203         Number of octets formatted on one line, if 0 then\n\
5204         return a single string instead of an array of lines\n\
5205     separator : string\n\
5206         String used to seperate each octet\n\
5207         If None it will be as if the empty string had been\n\
5208         passed and no separator will be used.\n\
5209 \n\
5210 Equivalent to calling data_to_hex(sec_item)\n\
5211 ");
5212 
5213 static PyObject *
SecItem_to_hex(SecItem * self,PyObject * args,PyObject * kwds)5214 SecItem_to_hex(SecItem *self, PyObject *args, PyObject *kwds)
5215 {
5216     static char *kwlist[] = {"octets_per_line", "separator", NULL};
5217     int octets_per_line = 0;
5218     char *separator = HEX_SEPARATOR_DEFAULT;
5219 
5220     TraceMethodEnter(self);
5221 
5222     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iz:to_hex", kwlist,
5223                                      &octets_per_line, &separator))
5224         return NULL;
5225 
5226     return raw_data_to_hex(self->item.data, self->item.len, octets_per_line, separator);
5227 }
5228 
5229 PyDoc_STRVAR(SecItem_to_base64_doc,
5230 "to_base64(chars_per_line=64, pem_type=) -> string or list of strings\n\
5231 \n\
5232 :Parameters:\n\
5233     chars_per_line : integer\n\
5234         Number of characters formatted on one line, if 0 then\n\
5235         return a single string instead of an array of lines\n\
5236     pem_type : string\n\
5237         If supplied the base64 encoded data will be wrapped with\n\
5238         a PEM header and footer whose type is the string.\n\
5239 \n\
5240 Format the binary data in the SecItem as base64 string(s).\n\
5241 Either a list of strings is returned or a single string.\n\
5242 \n\
5243 If chars_per_line is greater than zero then a list of\n\
5244 strings will be returned where each string contains\n\
5245 chars_per_line number of characters (except for the last\n\
5246 string in the list which will contain the remainder of the\n\
5247 characters). Returning a list of \"lines\" makes it convenient\n\
5248 for a caller to format a block of base64 data with line\n\
5249 wrapping. If chars_per_line is greater than zero indicating\n\
5250 a list result is desired a list is always returned even if\n\
5251 the number of characters would produce only a single line.\n\
5252 \n\
5253 If chars_per_line is zero then a single string is returned,\n\
5254 (no line splitting is performed).\n\
5255 \n\
5256 Examples:\n\
5257 \n\
5258 If data is:\n\
5259 \n\
5260 ::\n\
5261 \n\
5262     c8:94:00:9f:c2:8d:a2:5a:61:92:f2:cd:39:75:73:f4\n\
5263 \n\
5264 data.to_hex(0) will return the single string:\n\
5265 \n\
5266 ::\n\
5267 \n\
5268     'yJQAn8KNolphkvLNOXVz9A=='\n\
5269 \n\
5270 data.to_hex(5) will return a list of strings where each string has\n\
5271 a length of 5 (except the last string which may be shorter):\n\
5272 \n\
5273 ::\n\
5274 \n\
5275     [\n\
5276          'yJQAn',\n\
5277          '8KNol',\n\
5278          'phkvL',\n\
5279          'NOXVz',\n\
5280          '9A=='\n\
5281     ]\n\
5282 \n\
5283 If you specify the pem_type optional parameter the return value\n\
5284 will be a list of strings whose first and last strings will be a\n\
5285 PEM header and footer. For example if pem_type='CERTIFICATE'\n\
5286 then the return value will be like this:\n\
5287 \n\
5288 ::\n\
5289 \n\
5290     [\n\
5291         '-----BEGIN CERTIFICATE-----',\n\
5292         'yJQAn8KNolphkvLNOXVz9A=='\n\
5293         '-----END CERTIFICATE-----'\n\
5294     ]\n\
5295 \n\
5296 When a list of strings is returned it is easy to form a single\n\
5297 text block using the line ending of your choice, for example:\n\
5298 \n\
5299 ::\n\
5300 \n\
5301     '\\n'.join(data.to_base64())\n\
5302 \n\
5303 Thus a PEM block can be formed like this:\n\
5304 \n\
5305 ::\n\
5306 \n\
5307     '\\n'.join(data.to_base64(pem_type='CERTIFICATE'))\n\
5308 \n\
5309 ");
5310 
5311 static PyObject *
SecItem_to_base64(SecItem * self,PyObject * args,PyObject * kwds)5312 SecItem_to_base64(SecItem *self, PyObject *args, PyObject *kwds)
5313 {
5314     static char *kwlist[] = {"chars_per_line", "pem_type", NULL};
5315     int chars_per_line = 64;
5316     char *pem_type = NULL;
5317 
5318     TraceMethodEnter(self);
5319 
5320     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|is:to_base64", kwlist,
5321                                      &chars_per_line, &pem_type))
5322         return NULL;
5323 
5324     return SECItem_to_base64(&self->item, chars_per_line, pem_type);
5325 }
5326 
5327 PyDoc_STRVAR(SecItem_der_to_hex_doc,
5328 "der_to_hex(octets_per_line=0, separator=':') -> string or list of strings\n\
5329 \n\
5330 :Parameters:\n\
5331     octets_per_line : integer\n\
5332         Number of octets formatted on one line, if 0 then\n\
5333         return a single string instead of an array of lines\n\
5334     separator : string\n\
5335         String used to seperate each octet\n\
5336         If None it will be as if the empty string had been\n\
5337         passed and no separator will be used.\n\
5338 \n\
5339 Interpret the SecItem as containing DER encoded data consisting\n\
5340 of a <type,length,value> triplet (e.g. TLV). This function skips\n\
5341 the type and length components and returns the value component as\n\
5342 a hexadecimal string or a list of hexidecimal strings with a\n\
5343 maximum of octets_per_line in each list element. See data_to_hex()\n\
5344 for a more detailed explanation.\n\
5345 ");
5346 
5347 static PyObject *
SecItem_der_to_hex(SecItem * self,PyObject * args,PyObject * kwds)5348 SecItem_der_to_hex(SecItem *self, PyObject *args, PyObject *kwds)
5349 {
5350     static char *kwlist[] = {"octets_per_line", "separator", NULL};
5351     int octets_per_line = 0;
5352     char *separator = HEX_SEPARATOR_DEFAULT;
5353     SECItem tmp_item = self->item;
5354 
5355     TraceMethodEnter(self);
5356 
5357     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iz:der_to_hex", kwlist,
5358                                      &octets_per_line, &separator))
5359         return NULL;
5360 
5361 
5362     tmp_item = self->item;
5363     if (sec_strip_tag_and_length(&tmp_item) != SECSuccess) {
5364         PyErr_SetString(PyExc_ValueError, "malformed ASN.1 DER data");
5365         return NULL;
5366     }
5367 
5368     return raw_data_to_hex(tmp_item.data, tmp_item.len, octets_per_line, separator);
5369 }
5370 
5371 static PyObject *
SecItem_format_lines(SecItem * self,PyObject * args,PyObject * kwds)5372 SecItem_format_lines(SecItem *self, PyObject *args, PyObject *kwds)
5373 {
5374     static char *kwlist[] = {"level", NULL};
5375     int level = 0;
5376     PyObject *lines = NULL;
5377     PyObject *obj1 = NULL;
5378 
5379     TraceMethodEnter(self);
5380 
5381     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:format_lines", kwlist, &level))
5382         return NULL;
5383 
5384     if ((lines = PyList_New(0)) == NULL) {
5385         return NULL;
5386     }
5387 
5388     FMT_LABEL_AND_APPEND(lines, _("Data"), level, fail);
5389     if ((obj1 = SecItem_get_data(self, NULL)) == NULL) {
5390         goto fail;
5391     }
5392     APPEND_OBJ_TO_HEX_LINES_AND_CLEAR(lines, obj1, level+1, fail);
5393 
5394     return lines;
5395  fail:
5396     Py_XDECREF(obj1);
5397     Py_XDECREF(lines);
5398     return NULL;
5399 }
5400 
5401 static PyObject *
SecItem_format(SecItem * self,PyObject * args,PyObject * kwds)5402 SecItem_format(SecItem *self, PyObject *args, PyObject *kwds)
5403 {
5404     TraceMethodEnter(self);
5405 
5406     return format_from_lines((format_lines_func)SecItem_format_lines, (PyObject *)self, args, kwds);
5407 }
5408 
5409 static PyMethodDef SecItem_methods[] = {
5410     {"format_lines",     (PyCFunction)SecItem_format_lines,     METH_VARARGS|METH_KEYWORDS, generic_format_lines_doc},
5411     {"format",           (PyCFunction)SecItem_format,           METH_VARARGS|METH_KEYWORDS, generic_format_doc},
5412     {"get_oid_sequence", (PyCFunction)SecItem_get_oid_sequence, METH_VARARGS|METH_KEYWORDS, SecItem_get_oid_sequence_doc},
5413     {"get_integer",      (PyCFunction)SecItem_get_integer,      METH_NOARGS,                SecItem_get_integer_doc},
5414     {"to_hex",           (PyCFunction)SecItem_to_hex,           METH_VARARGS|METH_KEYWORDS, SecItem_to_hex_doc},
5415     {"to_base64",        (PyCFunction)SecItem_to_base64,        METH_VARARGS|METH_KEYWORDS, SecItem_to_base64_doc},
5416     {"der_to_hex",       (PyCFunction)SecItem_der_to_hex,       METH_VARARGS|METH_KEYWORDS, SecItem_der_to_hex_doc},
5417     {NULL, NULL}  /* Sentinel */
5418 };
5419 
5420 /* =========================== Class Construction =========================== */
5421 
5422 static PyObject *
SecItem_new(PyTypeObject * type,PyObject * args,PyObject * kwds)5423 SecItem_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
5424 {
5425     SecItem *self;
5426 
5427     TraceObjNewEnter(type);
5428 
5429     if ((self = (SecItem *)type->tp_alloc(type, 0)) == NULL) {
5430         return NULL;
5431     }
5432     self->item.type = 0;
5433     self->item.len = 0;
5434     self->item.data = NULL;
5435     self->kind = SECITEM_unknown;
5436     self->buffer_exports = 0;
5437 
5438     TraceObjNewLeave(self);
5439     return (PyObject *)self;
5440 }
5441 
5442 static void
SecItem_dealloc(SecItem * self)5443 SecItem_dealloc(SecItem* self)
5444 {
5445     TraceMethodEnter(self);
5446 
5447     if (self->buffer_exports > 0) {
5448         PyErr_SetString(PyExc_SystemError,
5449                         "deallocated SecItem object has exported buffers");
5450         PyErr_Print();
5451     }
5452 
5453     if (self->item.data) {
5454         /* zero out memory block before freeing */
5455         memset(self->item.data, 0, self->item.len);
5456         PyMem_FREE(self->item.data);
5457     }
5458 
5459     Py_TYPE(self)->tp_free((PyObject*)self);
5460 }
5461 
5462 static void
SecItem_decref(SecItem * self)5463 SecItem_decref(SecItem* self)
5464 {
5465     TraceMethodEnter(self);
5466 
5467     Py_XDECREF(self);
5468 }
5469 
5470 PyDoc_STRVAR(SecItem_doc,
5471 "SecItem(data=None, type=siBuffer, ascii=False)\n\
5472 \n\
5473 :Parameters:\n\
5474     data : any read buffer compatible object (e.g. buffer or string)\n\
5475         raw data to initialize from\n\
5476     type : int\n\
5477         SECItemType constant (e.g. si*)\n\
5478     ascii : bool\n\
5479         If true then data is interpretted as base64 encoded.\n\
5480         A PEM header and footer is permissible, if present the\n\
5481         base64 data will be found inside the PEM delimiters.\n\
5482 \n\
5483 A SecItem is a block of binary data. It contains the data, a count of\n\
5484 the number of octets in the data and optionally a type describing the\n\
5485 contents of the data. SecItem's are used throughout NSS to pass blocks\n\
5486 of binary data back and forth. Because the binary data is often DER\n\
5487 (Distinguished Encoding Rule) ASN.1 data the data is often referred to\n\
5488 as 'der'.\n\
5489 \n\
5490 SecItem's are often returned by NSS functions.\n\
5491 \n\
5492 You can create and initialize a SecItem yourself by passing the data\n\
5493 to the SecItem constructor. If you do initialize the data you may either\n\
5494 pass binary data or text (when ascii == True). When you pass ascii data\n\
5495 it will be interpreted as base64 encoded binary data. The base64 text may\n\
5496 optionally be wrapped inside PEM delimiters, but PEM format is not required.\n\
5497 ");
5498 static int
SecItem_init(SecItem * self,PyObject * args,PyObject * kwds)5499 SecItem_init(SecItem *self, PyObject *args, PyObject *kwds)
5500 {
5501     static char *kwlist[] = {"data", "type", "ascii", NULL};
5502     const void *buffer = NULL;
5503     Py_ssize_t buffer_len;
5504     int type = siBuffer;
5505     int ascii = 0;
5506 
5507     TraceMethodEnter(self);
5508 
5509     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|z#ii:SecItem", kwlist,
5510                                      &buffer, &buffer_len, &type, &ascii))
5511         return -1;
5512 
5513     if (buffer) {
5514         if (ascii) {
5515             SECItem binary;
5516 
5517             if (base64_to_SECItem(&binary, (char *)buffer, buffer_len) != SECSuccess) {
5518                 return -1;
5519             }
5520 
5521             if (SecItem_init_from_data(self, binary.data, binary.len,
5522                                        type, SECITEM_buffer) != 0) {
5523                 SECITEM_FreeItem(&binary, PR_FALSE);
5524                 return -1;
5525             }
5526             SECITEM_FreeItem(&binary, PR_FALSE);
5527 
5528         } else {
5529             if (SecItem_init_from_data(self, buffer, buffer_len,
5530                                        type, SECITEM_buffer) != 0) {
5531                 return -1;
5532             }
5533         }
5534     } else {                    /* empty buffer */
5535         self->kind = SECITEM_buffer;
5536         self->item.type = siBuffer;
5537         self->item.len = 0;
5538         self->item.data = NULL;
5539     }
5540 
5541     return 0;
5542 }
5543 
5544 static PyObject *
SecItem_str(SecItem * self)5545 SecItem_str(SecItem *self)
5546 {
5547     PyObject *return_value = NULL;
5548 
5549     switch(self->kind) {
5550     case SECITEM_dist_name:
5551         {
5552             char *name;
5553 
5554             if ((name = CERT_DerNameToAscii(&self->item)) == NULL) {
5555                 return set_nspr_error(NULL);
5556             }
5557             return_value = PyUnicode_FromString(name);
5558             PORT_Free(name);
5559         }
5560         break;
5561     case SECITEM_algorithm:
5562         return oid_secitem_to_pystr_desc(&self->item);
5563     case SECITEM_buffer:
5564         return secitem_to_pystr_hex(&self->item);
5565     default:
5566         return der_any_secitem_to_pystr(&self->item);
5567         break;
5568     }
5569     return return_value;
5570 }
5571 
5572 static PyObject *
SecItem_richcompare(SecItem * self,SecItem * other,int op)5573 SecItem_richcompare(SecItem *self, SecItem *other, int op)
5574 {
5575     int cmp_result = 0;
5576 
5577     if (!PySecItem_Check(other)) {
5578         PyErr_SetString(PyExc_TypeError, "Bad type, must be SecItem");
5579         return NULL;
5580     }
5581 
5582 
5583     if (self->item.data == NULL && other->item.data == NULL) {
5584         cmp_result = 0;
5585     }
5586 
5587     if (self->item.len == 0 && other->item.len == 0) {
5588         cmp_result = 0;
5589     }
5590 
5591     if (self->item.len > other->item.len) {
5592         cmp_result = 1;
5593     }
5594 
5595     if (self->item.len < other->item.len) {
5596         cmp_result = -1;
5597     }
5598 
5599     if (self->item.data != NULL && other->item.data != NULL) {
5600         cmp_result = memcmp(self->item.data, other->item.data, self->item.len);
5601     }
5602 
5603 
5604     RETURN_COMPARE_RESULT(op, cmp_result)
5605 }
5606 
5607 /* =========================== Buffer Protocol ========================== */
5608 
5609 
SecItem_GetBuffer(PyObject * obj,Py_buffer * view,int flags)5610 static int SecItem_GetBuffer(PyObject *obj, Py_buffer *view, int flags)
5611 {
5612     int ret;
5613     SecItem *self = (SecItem *)obj;
5614 
5615     if (view == NULL) {
5616         self->buffer_exports++;
5617         return 0;
5618     }
5619 
5620     /*
5621      * Fills in a buffer-info structure correctly for an exporter that
5622      * can only share a contiguous chunk of memory of unsigned bytes
5623      * of the given length. Returns 0 on success and -1 (with raising
5624      * an error) on error.
5625      */
5626     ret = PyBuffer_FillInfo(view,            /* view to be initialized */
5627                             obj,             /* self, this SecItem instance */
5628                             self->item.data, /* data pointer */
5629                             self->item.len,  /* data length in octets */
5630                             0,               /* readonly */
5631                             flags);          /* flags */
5632     if (ret >= 0) {
5633         self->buffer_exports++;
5634     }
5635     return ret;
5636 }
5637 
SecItem_ReleaseBuffer(PyObject * obj,Py_buffer * view)5638 static void SecItem_ReleaseBuffer(PyObject *obj, Py_buffer *view)
5639 {
5640     SecItem *self = (SecItem *)obj;
5641 
5642     self->buffer_exports--;
5643 }
5644 
5645 #if PY_MAJOR_VERSION >= 3
5646 
5647 static PyBufferProcs SecItem_as_buffer = {
5648     SecItem_GetBuffer,          /* bf_getbuffer */
5649     SecItem_ReleaseBuffer,      /* bf_releasebuffer */
5650 };
5651 
5652 #else /* PY_MAJOR_VERSION < 3 */
5653 
5654 static Py_ssize_t
SecItem_buffer_getbuf(PyObject * obj,Py_ssize_t index,void ** ptr)5655 SecItem_buffer_getbuf(PyObject *obj, Py_ssize_t index, void **ptr)
5656 {
5657     SecItem *self = (SecItem *) obj;
5658     if (index != 0) {
5659         PyErr_SetString(PyExc_SystemError, "Accessing non-existent segment");
5660         return -1;
5661     }
5662     *ptr = self->item.data;
5663     return self->item.len;
5664 }
5665 
5666 static Py_ssize_t
SecItem_buffer_getsegcount(PyObject * obj,Py_ssize_t * lenp)5667 SecItem_buffer_getsegcount(PyObject *obj, Py_ssize_t *lenp)
5668 {
5669     if (lenp)
5670         *lenp = 1;
5671     return 1;
5672 }
5673 
5674 static PyBufferProcs SecItem_as_buffer = {
5675     SecItem_buffer_getbuf,			/* bf_getreadbuffer */
5676     SecItem_buffer_getbuf,			/* bf_getwritebuffer */
5677     SecItem_buffer_getsegcount,			/* bf_getsegcount */
5678     NULL,					/* bf_getcharbuffer */
5679     SecItem_GetBuffer,				/* bf_getbuffer */
5680     SecItem_ReleaseBuffer,			/* bf_releasebuffer */
5681 };
5682 
5683 #endif /* PY_MAJOR_VERSION >= 3 */
5684 
5685 static Py_ssize_t
SecItem_length(SecItem * self)5686 SecItem_length(SecItem *self)
5687 {
5688     return self->item.len;
5689 }
5690 
5691 static PyObject *
SecItem_item(SecItem * self,register Py_ssize_t i)5692 SecItem_item(SecItem *self, register Py_ssize_t i)
5693 {
5694     char octet;
5695 
5696     if (i < 0 || i >= self->item.len) {
5697         PyErr_SetString(PyExc_IndexError, "SecItem index out of range");
5698         return NULL;
5699     }
5700     octet = self->item.data[i];
5701     return PyBytes_FromStringAndSize(&octet, 1);
5702 }
5703 
5704 /* slice a[i:j] consists of octets a[i] ... a[j-1], j -- may be negative! */
5705 static PyObject *
SecItem_slice(SecItem * a,Py_ssize_t i,Py_ssize_t j)5706 SecItem_slice(SecItem *a, Py_ssize_t i, Py_ssize_t j)
5707 {
5708     if (i < 0)
5709         i = 0;
5710     if (j < 0)
5711         j = 0;
5712     if (j > SecItem_GET_SIZE(a))
5713         j = SecItem_GET_SIZE(a);
5714     if (j < i)
5715         j = i;
5716     return PyBytes_FromStringAndSize((const char *)(a->item.data + i), j-i);
5717 }
5718 
5719 static PyObject*
SecItem_subscript(SecItem * self,PyObject * item)5720 SecItem_subscript(SecItem *self, PyObject* item)
5721 {
5722     if (PyIndex_Check(item)) {
5723         Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
5724         if (i == -1 && PyErr_Occurred())
5725             return NULL;
5726         if (i < 0)
5727             i += SecItem_GET_SIZE(self);
5728         return SecItem_item(self, i);
5729     }
5730     else if (PySlice_Check(item)) {
5731         Py_ssize_t start, stop, step, slice_len, cur, i;
5732         unsigned char* src;
5733         unsigned char* dst;
5734         PyObject* result;
5735 
5736 #if PY_MAJOR_VERSION >= 3
5737         /* The only difference between Py2 and Py3 is Py2 needs (PySliceObject *) cast on 1st parameter */
5738         if (PySlice_GetIndicesEx(item, SecItem_GET_SIZE(self),
5739 				 &start, &stop, &step, &slice_len) < 0) {
5740             return NULL;
5741         }
5742 #else
5743         if (PySlice_GetIndicesEx((PySliceObject *)item, SecItem_GET_SIZE(self),
5744 				 &start, &stop, &step, &slice_len) < 0) {
5745             return NULL;
5746         }
5747 #endif
5748 
5749         if (slice_len <= 0) {
5750             return PyBytes_FromStringAndSize("", 0);
5751         } else if (step == 1) {
5752             return PyBytes_FromStringAndSize((char *)self->item.data + start, slice_len);
5753         } else {
5754             src = self->item.data;
5755             if ((result = PyBytes_FromStringAndSize(NULL, slice_len)) == NULL) {
5756                 return NULL;
5757             }
5758             dst = (unsigned char *)PyBytes_AsString(result);
5759             for (cur = start, i = 0; i < slice_len; cur += step, i++) {
5760                 dst[i] = src[cur];
5761             }
5762             return result;
5763         }
5764     } else {
5765         PyErr_Format(PyExc_TypeError, "SecItem indices must be integers, not %.200s",
5766                      Py_TYPE(item)->tp_name);
5767         return NULL;
5768     }
5769 }
5770 
5771 static PySequenceMethods SecItem_as_sequence = {
5772     (lenfunc)SecItem_length,			/* sq_length */
5773     0,						/* sq_concat */
5774     0,						/* sq_repeat */
5775     (ssizeargfunc)SecItem_item,			/* sq_item */
5776     (ssizessizeargfunc)SecItem_slice,		/* sq_slice */
5777     0,						/* sq_ass_item */
5778     0,						/* sq_ass_slice */
5779     0,						/* sq_contains */
5780     0,						/* sq_inplace_concat */
5781     0,						/* sq_inplace_repeat */
5782 };
5783 
5784 static PyMappingMethods SecItem_as_mapping = {
5785     (lenfunc)SecItem_length,			/* mp_length */
5786     (binaryfunc)SecItem_subscript,		/* mp_subscript */
5787     0,						/* mp_ass_subscript */
5788 };
5789 
5790 static PyTypeObject SecItemType = {
5791     PyVarObject_HEAD_INIT(NULL, 0)
5792     "nss.nss.SecItem",				/* tp_name */
5793     sizeof(SecItem),				/* tp_basicsize */
5794     0,						/* tp_itemsize */
5795     (destructor)SecItem_dealloc,		/* tp_dealloc */
5796     0,						/* tp_print */
5797     0,						/* tp_getattr */
5798     0,						/* tp_setattr */
5799     0,						/* tp_compare */
5800     0,						/* tp_repr */
5801     0,						/* tp_as_number */
5802     &SecItem_as_sequence,			/* tp_as_sequence */
5803     &SecItem_as_mapping,			/* tp_as_mapping */
5804     0,						/* tp_hash */
5805     0,						/* tp_call */
5806     (reprfunc)SecItem_str,			/* tp_str */
5807     0,						/* tp_getattro */
5808     0,						/* tp_setattro */
5809     &SecItem_as_buffer,				/* tp_as_buffer */
5810 #if PY_MAJOR_VERSION >= 3
5811     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,	/* tp_flags */
5812 #else
5813     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_NEWBUFFER,	/* tp_flags */
5814 #endif
5815     SecItem_doc,				/* tp_doc */
5816     0,						/* tp_traverse */
5817     0,						/* tp_clear */
5818     (richcmpfunc)SecItem_richcompare,		/* tp_richcompare */
5819     0,						/* tp_weaklistoffset */
5820     0,						/* tp_iter */
5821     0,						/* tp_iternext */
5822     SecItem_methods,				/* tp_methods */
5823     SecItem_members,				/* tp_members */
5824     SecItem_getseters,				/* tp_getset */
5825     0,						/* tp_base */
5826     0,						/* tp_dict */
5827     0,						/* tp_descr_get */
5828     0,						/* tp_descr_set */
5829     0,						/* tp_dictoffset */
5830     (initproc)SecItem_init,			/* tp_init */
5831     0,						/* tp_alloc */
5832     SecItem_new,				/* tp_new */
5833 };
5834 
5835 /*
5836  * NSS WART - We always have to copy the SECItem because there are
5837  * more than 1 way to free a SECItem pointer depending on how it was
5838  * allocated.
5839  */
5840 
5841 static int
SecItem_init_from_data(SecItem * self,const void * data,Py_ssize_t len,SECItemType type,SECItemKind kind)5842 SecItem_init_from_data(SecItem *self, const void *data, Py_ssize_t len,
5843                        SECItemType type, SECItemKind kind)
5844 {
5845     self->item.type = type;
5846     self->item.len = len;
5847     if ((self->item.data = PyMem_MALLOC(len)) == NULL) {
5848         PyErr_Format(PyExc_MemoryError,
5849                      "not enough memory to copy buffer of size %zd into SecItem",
5850                      len);
5851         return -1;
5852     }
5853     memmove(self->item.data, data, len);
5854     self->kind = kind;
5855 
5856     return 0;
5857 }
5858 
5859 static PyObject *
SecItem_new_from_SECItem(const SECItem * item,SECItemKind kind)5860 SecItem_new_from_SECItem(const SECItem *item, SECItemKind kind)
5861 {
5862     SecItem *self = NULL;
5863 
5864     TraceObjNewEnter(NULL);
5865 
5866     if (!item) {
5867         return NULL;
5868     }
5869 
5870     if ((self = (SecItem *) SecItemType.tp_new(&SecItemType, NULL, NULL)) == NULL) {
5871         return NULL;
5872     }
5873 
5874     if (SecItem_init_from_data(self, item->data, item->len,
5875                                item->type, kind) != 0) {
5876         Py_CLEAR(self);
5877         return PyErr_NoMemory();
5878     }
5879 
5880     TraceObjNewLeave(self);
5881     return (PyObject *) self;
5882 }
5883 
5884 static PyObject *
SecItem_new_alloc(size_t len,SECItemType type,SECItemKind kind)5885 SecItem_new_alloc(size_t len, SECItemType type, SECItemKind kind)
5886 {
5887     SecItem *self = NULL;
5888 
5889     TraceObjNewEnter(NULL);
5890 
5891     if ((self = (SecItem *) SecItemType.tp_new(&SecItemType, NULL, NULL)) == NULL) {
5892         return NULL;
5893     }
5894 
5895     self->item.type = type;
5896     self->item.len = len;
5897     if ((self->item.data = PyMem_MALLOC(len)) == NULL) {
5898         Py_CLEAR(self);
5899         return PyErr_NoMemory();
5900     }
5901 
5902     self->kind = kind;
5903 
5904     TraceObjNewLeave(self);
5905     return (PyObject *) self;
5906 }
5907 
5908 /* ========================================================================== */
5909 /* ============================ AlgorithmID Class =========================== */
5910 /* ========================================================================== */
5911 
5912 /*
5913  * NSS WART BEGIN
5914  *
5915  * The following have no public definition, copied from secutil.c
5916  */
5917 typedef struct secuPBEParamsStr {
5918     SECItem salt;
5919     SECItem iterationCount;
5920     SECItem keyLength;
5921     SECAlgorithmID cipherAlg;
5922     SECAlgorithmID kdfAlg;
5923 } secuPBEParams;
5924 
5925 SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate);
5926 
5927 /* SECOID_PKCS5_PBKDF2 */
5928 const SEC_ASN1Template secuKDF2Params[] =
5929 {
5930     { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(secuPBEParams) },
5931     { SEC_ASN1_OCTET_STRING, offsetof(secuPBEParams, salt) },
5932     { SEC_ASN1_INTEGER, offsetof(secuPBEParams, iterationCount) },
5933     { SEC_ASN1_INTEGER, offsetof(secuPBEParams, keyLength) },
5934     { SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(secuPBEParams, kdfAlg),
5935         SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
5936     { 0 }
5937 };
5938 
5939 /* PKCS5v1 & PKCS12 */
5940 const SEC_ASN1Template secuPBEParamsTemp[] =
5941 {
5942     { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(secuPBEParams) },
5943     { SEC_ASN1_OCTET_STRING, offsetof(secuPBEParams, salt) },
5944     { SEC_ASN1_INTEGER, offsetof(secuPBEParams, iterationCount) },
5945     { 0 }
5946 };
5947 
5948 /* SEC_OID_PKCS5_PBES2, SEC_OID_PKCS5_PBMAC1 */
5949 const SEC_ASN1Template secuPBEV2Params[] =
5950 {
5951     { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(secuPBEParams)},
5952     { SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(secuPBEParams, kdfAlg),
5953         SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
5954     { SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(secuPBEParams, cipherAlg),
5955         SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
5956     { 0 }
5957 };
5958 
5959 /*
5960  * NSS WART END
5961  */
5962 
5963 #ifdef HAVE_RSA_PSS
5964 static PyObject *
RSAPSSParams_format_lines(SECItem * item,int level)5965 RSAPSSParams_format_lines(SECItem *item, int level)
5966 {
5967     SECKEYRSAPSSParams params;
5968     SECAlgorithmID mask_hash_alg;
5969     PRArenaPool *arena = NULL;
5970     PyObject *lines = NULL;
5971     PyObject *obj = NULL;
5972     PyObject *obj1 = NULL;
5973 
5974     /* allocate an arena to use */
5975     if ((arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE)) == NULL ) {
5976         set_nspr_error(NULL);
5977         return NULL;
5978     }
5979 
5980     if ((lines = PyList_New(0)) == NULL) {
5981         return NULL;
5982     }
5983 
5984     PORT_Memset(&params, 0, sizeof params);
5985 
5986     if (SEC_QuickDERDecodeItem(arena, &params,
5987                                SEC_ASN1_GET(SECKEY_RSAPSSParamsTemplate),
5988                                item) != SECSuccess) {
5989         goto fail;
5990     }
5991 
5992     if (params.hashAlg) {
5993         obj = oid_secitem_to_pystr_desc(&params.hashAlg->algorithm);
5994     } else {
5995         obj = PyUnicode_FromString("default, SHA-1");
5996     }
5997     FMT_OBJ_AND_APPEND(lines, _("Hash algorithm"), obj, level, fail);
5998     Py_CLEAR(obj);
5999 
6000     if (params.maskAlg) {
6001         obj = oid_secitem_to_pystr_desc(&params.maskAlg->algorithm);
6002         if (SEC_QuickDERDecodeItem(arena, &mask_hash_alg,
6003                                    SEC_ASN1_GET(SECOID_AlgorithmIDTemplate),
6004                                    &params.maskAlg->parameters) == SECSuccess) {
6005             obj1 = oid_secitem_to_pystr_desc(&mask_hash_alg.algorithm);
6006         } else {
6007             obj1 = PyUnicode_FromString("Invalid mask generation algorithm parameters");
6008         }
6009     } else {
6010         obj = PyUnicode_FromString("default, MGF1");
6011         obj1 = PyUnicode_FromString("default, SHA-1");
6012     }
6013     FMT_OBJ_AND_APPEND(lines, _("Mask Algorithm"), obj, level, fail);
6014     Py_CLEAR(obj);
6015 
6016     FMT_OBJ_AND_APPEND(lines, _("Mask hash algorithm"), obj1, level, fail);
6017     Py_CLEAR(obj1);
6018 
6019     if (params.saltLength.data) {
6020         obj = integer_secitem_to_pystr(&params.saltLength);
6021     } else {
6022         obj = PyUnicode_FromString("default, 20");
6023     }
6024     FMT_OBJ_AND_APPEND(lines, _("Salt length"), obj, level, fail);
6025     Py_CLEAR(obj);
6026 
6027     PORT_FreeArena(arena, PR_FALSE);
6028     return lines;
6029 
6030  fail:
6031     Py_XDECREF(obj);
6032     Py_XDECREF(obj1);
6033     Py_XDECREF(lines);
6034     PORT_FreeArena(arena, PR_FALSE);
6035     return NULL;
6036 }
6037 #endif
6038 
6039 static PyObject *
KDF2Params_format_lines(SECItem * item,int level)6040 KDF2Params_format_lines(SECItem *item, int level)
6041 {
6042     secuPBEParams params;
6043     PRArenaPool *arena = NULL;
6044     PyObject *lines = NULL;
6045     PyObject *obj = NULL;
6046 
6047     TraceMethodEnter(NULL);
6048 
6049     /* allocate an arena to use */
6050     if ((arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE)) == NULL ) {
6051         set_nspr_error(NULL);
6052         return NULL;
6053     }
6054 
6055     if ((lines = PyList_New(0)) == NULL) {
6056         return NULL;
6057     }
6058 
6059     PORT_Memset(&params, 0, sizeof params);
6060 
6061     if (SEC_QuickDERDecodeItem(arena, &params, secuKDF2Params, item) != SECSuccess) {
6062         goto fail;
6063     }
6064 
6065     obj = secitem_to_pystr_hex(&params.salt);
6066     FMT_OBJ_AND_APPEND(lines, _("Salt"), obj, level, fail);
6067     Py_CLEAR(obj);
6068 
6069     obj = integer_secitem_to_pystr(&params.iterationCount);
6070     FMT_OBJ_AND_APPEND(lines, _("Iteration Count"), obj, level, fail);
6071     Py_CLEAR(obj);
6072 
6073     obj = integer_secitem_to_pystr(&params.keyLength);
6074     FMT_OBJ_AND_APPEND(lines, _("Key Length"), obj, level, fail);
6075     Py_CLEAR(obj);
6076 
6077     obj = AlgorithmID_new_from_SECAlgorithmID(&params.kdfAlg);
6078     FMT_LABEL_AND_APPEND(lines, _("KDF Algorithm"), level, fail);
6079     CALL_FORMAT_LINES_AND_APPEND(lines, obj, level+1, fail);
6080     Py_CLEAR(obj);
6081 
6082     PORT_FreeArena(arena, PR_FALSE);
6083     return lines;
6084 
6085  fail:
6086     Py_XDECREF(obj);
6087     Py_XDECREF(lines);
6088     PORT_FreeArena(arena, PR_FALSE);
6089     return NULL;
6090 }
6091 
6092 static PyObject *
PKCS5V2Params_format_lines(SECItem * item,int level)6093 PKCS5V2Params_format_lines(SECItem *item, int level)
6094 {
6095     secuPBEParams params;
6096     PRArenaPool *arena = NULL;
6097     PyObject *lines = NULL;
6098     PyObject *obj = NULL;
6099 
6100     TraceMethodEnter(NULL);
6101 
6102     /* allocate an arena to use */
6103     if ((arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE)) == NULL ) {
6104         set_nspr_error(NULL);
6105         return NULL;
6106     }
6107 
6108     if ((lines = PyList_New(0)) == NULL) {
6109         return NULL;
6110     }
6111 
6112     PORT_Memset(&params, 0, sizeof params);
6113 
6114     if (SEC_QuickDERDecodeItem(arena, &params, secuPBEV2Params, item) != SECSuccess) {
6115         goto fail;
6116     }
6117 
6118     obj = AlgorithmID_new_from_SECAlgorithmID(&params.kdfAlg);
6119     FMT_LABEL_AND_APPEND(lines, _("KDF"), level, fail);
6120     CALL_FORMAT_LINES_AND_APPEND(lines, obj, level+1, fail);
6121     Py_CLEAR(obj);
6122 
6123     obj = AlgorithmID_new_from_SECAlgorithmID(&params.cipherAlg);
6124     FMT_LABEL_AND_APPEND(lines, _("Cipher"), level, fail);
6125     CALL_FORMAT_LINES_AND_APPEND(lines, obj, level+1, fail);
6126     Py_CLEAR(obj);
6127 
6128     PORT_FreeArena(arena, PR_FALSE);
6129     return lines;
6130 
6131  fail:
6132     Py_XDECREF(obj);
6133     Py_XDECREF(lines);
6134     PORT_FreeArena(arena, PR_FALSE);
6135     return NULL;
6136 }
6137 
6138 static PyObject *
PBEParams_format_lines(SECItem * item,int level)6139 PBEParams_format_lines(SECItem *item, int level)
6140 {
6141     secuPBEParams params;
6142     PRArenaPool *arena = NULL;
6143     PyObject *lines = NULL;
6144     PyObject *obj = NULL;
6145 
6146     TraceMethodEnter(NULL);
6147 
6148     /* allocate an arena to use */
6149     if ((arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE)) == NULL ) {
6150         set_nspr_error(NULL);
6151         return NULL;
6152     }
6153 
6154     if ((lines = PyList_New(0)) == NULL) {
6155         return NULL;
6156     }
6157 
6158     PORT_Memset(&params, 0, sizeof params);
6159 
6160     if (SEC_QuickDERDecodeItem(arena, &params, secuPBEParamsTemp, item) != SECSuccess) {
6161         goto fail;
6162     }
6163 
6164     obj = secitem_to_pystr_hex(&params.salt);
6165     FMT_OBJ_AND_APPEND(lines, _("Salt"), obj, level, fail);
6166     Py_CLEAR(obj);
6167 
6168     obj = integer_secitem_to_pystr(&params.iterationCount);
6169     FMT_OBJ_AND_APPEND(lines, _("Iteration Count"), obj, level, fail);
6170     Py_CLEAR(obj);
6171 
6172     PORT_FreeArena(arena, PR_FALSE);
6173     return lines;
6174 
6175  fail:
6176     Py_XDECREF(obj);
6177     Py_XDECREF(lines);
6178     PORT_FreeArena(arena, PR_FALSE);
6179     return NULL;
6180 }
6181 
6182 /* ============================ Attribute Access ============================ */
6183 
6184 static PyObject *
AlgorithmID_get_id_oid(AlgorithmID * self,void * closure)6185 AlgorithmID_get_id_oid(AlgorithmID *self, void *closure)
6186 {
6187     TraceMethodEnter(self);
6188 
6189     Py_INCREF(self->py_id);
6190     return self->py_id;
6191 }
6192 
6193 static PyObject *
AlgorithmID_get_id_tag(AlgorithmID * self,void * closure)6194 AlgorithmID_get_id_tag(AlgorithmID *self, void *closure)
6195 {
6196     TraceMethodEnter(self);
6197 
6198     return oid_secitem_to_pyint_tag(&self->id.algorithm);
6199 }
6200 
6201 static PyObject *
AlgorithmID_get_id_str(AlgorithmID * self,void * closure)6202 AlgorithmID_get_id_str(AlgorithmID *self, void *closure)
6203 {
6204     TraceMethodEnter(self);
6205 
6206     return oid_secitem_to_pystr_desc(&self->id.algorithm);
6207 }
6208 
6209 static PyObject *
AlgorithmID_get_parameters(AlgorithmID * self,void * closure)6210 AlgorithmID_get_parameters(AlgorithmID *self, void *closure)
6211 {
6212     TraceMethodEnter(self);
6213 
6214     Py_INCREF(self->py_parameters);
6215     return self->py_parameters;
6216 }
6217 
6218 static
6219 PyGetSetDef AlgorithmID_getseters[] = {
6220     {"id_oid",     (getter)AlgorithmID_get_id_oid,     (setter)NULL, "algorithm id OID as SecItem", NULL},
6221     {"id_tag",     (getter)AlgorithmID_get_id_tag,     (setter)NULL, "algorithm id TAG as a enumerated constant (e.g. tag)", NULL},
6222     {"id_str",     (getter)AlgorithmID_get_id_str,     (setter)NULL, "algorithm id as string description", NULL},
6223     {"parameters", (getter)AlgorithmID_get_parameters, (setter)NULL, "algorithm parameters as SecItem", NULL},
6224     {NULL}  /* Sentinel */
6225 };
6226 
6227 static PyMemberDef AlgorithmID_members[] = {
6228     {NULL}  /* Sentinel */
6229 };
6230 
6231 /* ============================== Class Methods ============================= */
6232 
6233 static PyObject *
AlgorithmID_format_lines(AlgorithmID * self,PyObject * args,PyObject * kwds)6234 AlgorithmID_format_lines(AlgorithmID *self, PyObject *args, PyObject *kwds)
6235 {
6236     static char *kwlist[] = {"level", NULL};
6237     int level = 0;
6238     PyObject *lines = NULL;
6239     PyObject *obj = NULL;
6240     SECOidTag alg_tag;
6241 
6242     TraceMethodEnter(self);
6243 
6244     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:format_lines", kwlist, &level))
6245         return NULL;
6246 
6247     if ((lines = PyList_New(0)) == NULL) {
6248         return NULL;
6249     }
6250 
6251     obj = oid_secitem_to_pystr_desc(&self->id.algorithm);
6252     FMT_OBJ_AND_APPEND(lines, _("Algorithm"), obj, level, fail);
6253     Py_CLEAR(obj);
6254 
6255     alg_tag = SECOID_GetAlgorithmTag(&self->id);
6256     if (SEC_PKCS5IsAlgorithmPBEAlgTag(alg_tag)) {
6257 	switch (alg_tag) {
6258 	case SEC_OID_PKCS5_PBKDF2:
6259             FMT_LABEL_AND_APPEND(lines, _("Parameters"), level, fail);
6260             obj = KDF2Params_format_lines(&self->id.parameters, level+1);
6261             APPEND_LINE_TUPLES_AND_CLEAR(lines, obj, fail);
6262 	    break;
6263 	case SEC_OID_PKCS5_PBES2:
6264             FMT_LABEL_AND_APPEND(lines, _("Encryption"), level, fail);
6265             obj = PKCS5V2Params_format_lines(&self->id.parameters, level+1);
6266             APPEND_LINE_TUPLES_AND_CLEAR(lines, obj, fail);
6267 	    break;
6268 	case SEC_OID_PKCS5_PBMAC1:
6269             FMT_LABEL_AND_APPEND(lines, _("MAC"), level, fail);
6270             obj = PKCS5V2Params_format_lines(&self->id.parameters, level+1);
6271             APPEND_LINE_TUPLES_AND_CLEAR(lines, obj, fail);
6272 	    break;
6273 	default:
6274             FMT_LABEL_AND_APPEND(lines, _("Parameters"), level, fail);
6275             obj = PBEParams_format_lines(&self->id.parameters, level+1);
6276             APPEND_LINE_TUPLES_AND_CLEAR(lines, obj, fail);
6277 	    break;
6278 	}
6279     }
6280 
6281 #ifdef HAVE_RSA_PSS
6282     if (alg_tag == SEC_OID_PKCS1_RSA_PSS_SIGNATURE) {
6283         FMT_LABEL_AND_APPEND(lines, _("Parameters"), level, fail);
6284         obj = RSAPSSParams_format_lines(&self->id.parameters, level+1);
6285         APPEND_LINE_TUPLES_AND_CLEAR(lines, obj, fail);
6286     }
6287 #endif
6288 
6289     if ((self->id.parameters.len == 0) ||
6290 	(self->id.parameters.len == 2 && memcmp(self->id.parameters.data, "\005\000", 2) == 0)) {
6291 	/* No arguments or NULL argument */
6292     } else {
6293 	/* Print args to algorithm */
6294         PyObject *hex_lines = NULL;
6295 
6296         if ((hex_lines = raw_data_to_hex(self->id.parameters.data, self->id.parameters.len,
6297                                          OCTETS_PER_LINE_DEFAULT, HEX_SEPARATOR_DEFAULT)) != NULL) {
6298             FMT_LABEL_AND_APPEND(lines, _("Raw Parameter Data"), level, fail);
6299             APPEND_LINES_AND_CLEAR(lines, hex_lines, level+1, fail);
6300         }
6301     }
6302 
6303     return lines;
6304  fail:
6305     Py_XDECREF(obj);
6306     Py_XDECREF(lines);
6307     return NULL;
6308 }
6309 
6310 static PyObject *
AlgorithmID_format(AlgorithmID * self,PyObject * args,PyObject * kwds)6311 AlgorithmID_format(AlgorithmID *self, PyObject *args, PyObject *kwds)
6312 {
6313     TraceMethodEnter(self);
6314 
6315     return format_from_lines((format_lines_func)AlgorithmID_format_lines, (PyObject *)self, args, kwds);
6316 }
6317 
6318 static PyObject *
AlgorithmID_str(AlgorithmID * self)6319 AlgorithmID_str(AlgorithmID *self)
6320 {
6321     PyObject *py_formatted_result = NULL;
6322 
6323     TraceMethodEnter(self);
6324 
6325     py_formatted_result =  AlgorithmID_format(self, empty_tuple, NULL);
6326     return py_formatted_result;
6327 
6328 }
6329 
6330 PyDoc_STRVAR(AlgorithmID_get_pbe_crypto_mechanism_doc,
6331 "get_pbe_crypto_mechanism(sym_key, padded=True) -> (mechanism, params)\n\
6332 \n\
6333 :Parameters:\n\
6334     sym_key : PK11SymKey object\n\
6335         The symmetric key returned from `PK11Slot.pbe_key_gen()`\n\
6336     padded : bool\n\
6337         Block ciphers require the input data to be a multiple of the cipher\n\
6338         block size. The necessary padding can be performed internally,\n\
6339         this is controlled by selecting a pad vs. non-pad cipher mechanism.\n\
6340         If the padded flag is True the returned mechanism will support\n\
6341         padding if possible. If you know you do not need or want a padded\n\
6342         mechanism set this flag to False. Selection of a padded mechanism\n\
6343         is performed internally by calling `nss.get_pad_mechanism()`.\n\
6344 \n\
6345 This function generates the parameters needed for\n\
6346 `nss.create_context_by_sym_key()`, for example:\n\
6347 \n\
6348     alg_id = nss.create_pbev2_algorithm_id()\n\
6349     sym_key = slot.pbe_key_gen(alg_id, password)\n\
6350     mechanism, params = alg_id.get_pbe_crypto_mechanism(sym_key)\n\
6351     encrypt_ctx = nss.create_context_by_sym_key(mechanism, nss.CKA_ENCRYPT, sym_key, params)\n\
6352 \n\
6353 ");
6354 
6355 static PyObject *
AlgorithmID_get_pbe_crypto_mechanism(AlgorithmID * self,PyObject * args,PyObject * kwds)6356 AlgorithmID_get_pbe_crypto_mechanism(AlgorithmID *self, PyObject *args, PyObject *kwds)
6357 {
6358     static char *kwlist[] = {"alg_id", "padded", NULL};
6359     PyPK11SymKey *py_sym_key = NULL;
6360     PyObject *py_padded = NULL;
6361     PRBool padded = PR_TRUE;
6362     CK_MECHANISM_TYPE mechanism;
6363     SecItem *py_pwitem = NULL;
6364     SECItem *params = NULL;
6365     PyObject *py_params = NULL;
6366     PyObject *tuple = NULL;
6367 
6368     TraceMethodEnter(self);
6369 
6370     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|O!:get_pbe_crypto_mechanism", kwlist,
6371                                       &PK11SymKeyType, &py_sym_key,
6372                                       &PyBool_Type, &py_padded))
6373         return NULL;
6374 
6375     if (py_padded) {
6376         padded = PyBoolAsPRBool(py_padded);
6377     }
6378 
6379     /*
6380      * PK11Slot_pbe_key_gen
6381      */
6382 
6383     py_pwitem = (SecItem *)PK11_GetSymKeyUserData(py_sym_key->pk11_sym_key);
6384 
6385 
6386     if ((mechanism = PK11_GetPBECryptoMechanism(&self->id, &params,
6387                                                 &py_pwitem->item)) == CKM_INVALID_MECHANISM) {
6388 
6389         return set_nspr_error(NULL);
6390     }
6391 
6392     if (padded) {
6393         mechanism = PK11_GetPadMechanism(mechanism);
6394     }
6395 
6396     if ((py_params = SecItem_new_from_SECItem(params, SECITEM_sym_key_params)) == NULL) {
6397         if (params) {
6398             SECITEM_ZfreeItem(params, PR_TRUE);
6399         }
6400         return NULL;
6401     }
6402     if (params) {
6403         SECITEM_ZfreeItem(params, PR_TRUE);
6404     }
6405 
6406     if ((tuple = PyTuple_New(2)) == NULL) {
6407         return NULL;
6408     }
6409 
6410     PyTuple_SetItem(tuple, 0, PyLong_FromLong(mechanism));
6411     PyTuple_SetItem(tuple, 1, py_params);
6412 
6413     return tuple;
6414 }
6415 
6416 PyDoc_STRVAR(AlgorithmID_get_pbe_iv_doc,
6417 "get_pbe_iv(password) -> SecItem\n\
6418 \n\
6419 :Parameters:\n\
6420     password : string\n\
6421         the password used to create the PBE Key\n\
6422 \n\
6423 Returns the IV (Initialization Vector) used for the PBE cipher.\n\
6424 ");
6425 
6426 static PyObject *
AlgorithmID_get_pbe_iv(AlgorithmID * self,PyObject * args)6427 AlgorithmID_get_pbe_iv(AlgorithmID *self, PyObject *args)
6428 {
6429     char *password = NULL;
6430     Py_ssize_t password_len = 0;
6431     SECItem pwitem;
6432     SECItem *iv;
6433     PyObject *py_iv = NULL;
6434 
6435     TraceMethodEnter(self);
6436 
6437     if (!PyArg_ParseTuple(args, "s#:get_pbe_iv",
6438                           &password, &password_len))
6439         return NULL;
6440 
6441     pwitem.data = (unsigned char *)password;
6442     pwitem.len = password_len;
6443 
6444     if ((iv = PK11_GetPBEIV(&self->id, &pwitem)) == NULL) {
6445         return set_nspr_error(NULL);
6446     }
6447 
6448     py_iv = SecItem_new_from_SECItem(iv, SECITEM_iv_param);
6449     SECITEM_FreeItem(iv, PR_TRUE);
6450     return py_iv;
6451 }
6452 
6453 static PyMethodDef AlgorithmID_methods[] = {
6454     {"format_lines",             (PyCFunction)AlgorithmID_format_lines,             METH_VARARGS|METH_KEYWORDS, generic_format_lines_doc},
6455     {"format",                   (PyCFunction)AlgorithmID_format,                   METH_VARARGS|METH_KEYWORDS, generic_format_doc},
6456     {"get_pbe_crypto_mechanism", (PyCFunction)AlgorithmID_get_pbe_crypto_mechanism, METH_VARARGS|METH_KEYWORDS, AlgorithmID_get_pbe_crypto_mechanism_doc},
6457     {"get_pbe_iv",               (PyCFunction)AlgorithmID_get_pbe_iv,               METH_VARARGS,               AlgorithmID_get_pbe_iv_doc},
6458     {NULL, NULL}  /* Sentinel */
6459 };
6460 
6461 
6462 /* =========================== Class Construction =========================== */
6463 
6464 static PyObject *
AlgorithmID_new(PyTypeObject * type,PyObject * args,PyObject * kwds)6465 AlgorithmID_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
6466 {
6467     AlgorithmID *self;
6468 
6469     TraceObjNewEnter(type);
6470 
6471     if ((self = (AlgorithmID *)type->tp_alloc(type, 0)) == NULL) {
6472         return NULL;
6473     }
6474 
6475     memset(&self->id, 0, sizeof(self->id));
6476     self->py_id = NULL;
6477     self->py_parameters = NULL;
6478 
6479     TraceObjNewLeave(self);
6480     return (PyObject *)self;
6481 }
6482 
6483 static int
AlgorithmID_traverse(AlgorithmID * self,visitproc visit,void * arg)6484 AlgorithmID_traverse(AlgorithmID *self, visitproc visit, void *arg)
6485 {
6486     TraceMethodEnter(self);
6487 
6488     Py_VISIT(self->py_id);
6489     Py_VISIT(self->py_parameters);
6490     return 0;
6491 }
6492 
6493 static int
AlgorithmID_clear(AlgorithmID * self)6494 AlgorithmID_clear(AlgorithmID* self)
6495 {
6496     TraceMethodEnter(self);
6497 
6498     Py_CLEAR(self->py_id);
6499     Py_CLEAR(self->py_parameters);
6500     return 0;
6501 }
6502 
6503 static void
AlgorithmID_dealloc(AlgorithmID * self)6504 AlgorithmID_dealloc(AlgorithmID* self)
6505 {
6506     TraceMethodEnter(self);
6507 
6508     AlgorithmID_clear(self);
6509     SECOID_DestroyAlgorithmID(&self->id, PR_FALSE);
6510     Py_TYPE(self)->tp_free((PyObject*)self);
6511 }
6512 
6513 PyDoc_STRVAR(AlgorithmID_doc,
6514 "An object representing a signature algorithm");
6515 
6516 static int
AlgorithmID_init(AlgorithmID * self,PyObject * args,PyObject * kwds)6517 AlgorithmID_init(AlgorithmID *self, PyObject *args, PyObject *kwds)
6518 {
6519     TraceMethodEnter(self);
6520 
6521     return 0;
6522 }
6523 
6524 static PyTypeObject AlgorithmIDType = {
6525     PyVarObject_HEAD_INIT(NULL, 0)
6526     "nss.nss.AlgorithmID",			/* tp_name */
6527     sizeof(AlgorithmID),			/* tp_basicsize */
6528     0,						/* tp_itemsize */
6529     (destructor)AlgorithmID_dealloc,		/* tp_dealloc */
6530     0,						/* tp_print */
6531     0,						/* tp_getattr */
6532     0,						/* tp_setattr */
6533     0,						/* tp_compare */
6534     0,						/* tp_repr */
6535     0,						/* tp_as_number */
6536     0,						/* tp_as_sequence */
6537     0,						/* tp_as_mapping */
6538     0,						/* tp_hash */
6539     0,						/* tp_call */
6540     (reprfunc)AlgorithmID_str,			/* tp_str */
6541     0,						/* tp_getattro */
6542     0,						/* tp_setattro */
6543     0,						/* tp_as_buffer */
6544     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,	/* tp_flags */
6545     AlgorithmID_doc,				/* tp_doc */
6546     (traverseproc)AlgorithmID_traverse,		/* tp_traverse */
6547     (inquiry)AlgorithmID_clear,			/* tp_clear */
6548     0,						/* tp_richcompare */
6549     0,						/* tp_weaklistoffset */
6550     0,						/* tp_iter */
6551     0,						/* tp_iternext */
6552     AlgorithmID_methods,			/* tp_methods */
6553     AlgorithmID_members,			/* tp_members */
6554     AlgorithmID_getseters,			/* tp_getset */
6555     0,						/* tp_base */
6556     0,						/* tp_dict */
6557     0,						/* tp_descr_get */
6558     0,						/* tp_descr_set */
6559     0,						/* tp_dictoffset */
6560     (initproc)AlgorithmID_init,			/* tp_init */
6561     0,						/* tp_alloc */
6562     AlgorithmID_new,				/* tp_new */
6563 };
6564 
6565 PyObject *
AlgorithmID_new_from_SECAlgorithmID(SECAlgorithmID * id)6566 AlgorithmID_new_from_SECAlgorithmID(SECAlgorithmID *id)
6567 {
6568     AlgorithmID *self = NULL;
6569 
6570     TraceObjNewEnter(NULL);
6571 
6572     if ((self = (AlgorithmID *) AlgorithmIDType.tp_new(&AlgorithmIDType, NULL, NULL)) == NULL) {
6573         return NULL;
6574     }
6575 
6576     if (SECOID_CopyAlgorithmID(NULL, &self->id, id) != SECSuccess) {
6577         set_nspr_error(NULL);
6578         Py_CLEAR(self);
6579         return NULL;
6580     }
6581 
6582     if ((self->py_id = SecItem_new_from_SECItem(&id->algorithm, SECITEM_algorithm)) == NULL) {
6583         SECOID_DestroyAlgorithmID(&self->id, PR_FALSE);
6584         Py_CLEAR(self);
6585         return NULL;
6586     }
6587 
6588     if ((self->py_parameters = SecItem_new_from_SECItem(&id->parameters, SECITEM_unknown)) == NULL) {
6589         SECOID_DestroyAlgorithmID(&self->id, PR_FALSE);
6590         Py_CLEAR(self);
6591         return NULL;
6592     }
6593 
6594     TraceObjNewLeave(self);
6595     return (PyObject *) self;
6596 }
6597 
6598 /* ========================================================================== */
6599 /* =========================== RSAGenParams Class =========================== */
6600 /* ========================================================================== */
6601 
6602 /* ============================ Attribute Access ============================ */
6603 
6604 static PyObject *
RSAGenParams_get_key_size(RSAGenParams * self,void * closure)6605 RSAGenParams_get_key_size(RSAGenParams *self, void *closure)
6606 {
6607     TraceMethodEnter(self);
6608 
6609     return PyLong_FromLong(self->params.keySizeInBits);
6610 
6611 }
6612 
6613 static int
RSAGenParams_set_key_size(RSAGenParams * self,PyObject * value,void * closure)6614 RSAGenParams_set_key_size(RSAGenParams *self, PyObject *value, void *closure)
6615 {
6616     TraceMethodEnter(self);
6617 
6618     if (value == NULL) {
6619         PyErr_SetString(PyExc_TypeError, "Cannot delete the key_size attribute");
6620         return -1;
6621     }
6622 
6623     if (!PyInteger_Check(value)) {
6624         PyErr_Format(PyExc_TypeError, "key_size must be a integer, not %.200s",
6625                      Py_TYPE(value)->tp_name);
6626         return -1;
6627     }
6628 
6629     self->params.keySizeInBits = PyLong_AsLong(value);
6630 
6631     return 0;
6632 }
6633 
6634 static PyObject *
RSAGenParams_get_public_exponent(RSAGenParams * self,void * closure)6635 RSAGenParams_get_public_exponent(RSAGenParams *self, void *closure)
6636 {
6637     TraceMethodEnter(self);
6638 
6639     return PyLong_FromLong(self->params.keySizeInBits);
6640 
6641 }
6642 
6643 static int
RSAGenParams_set_public_exponent(RSAGenParams * self,PyObject * value,void * closure)6644 RSAGenParams_set_public_exponent(RSAGenParams *self, PyObject *value, void *closure)
6645 {
6646     TraceMethodEnter(self);
6647 
6648     if (value == NULL) {
6649         PyErr_SetString(PyExc_TypeError, "Cannot delete the public_exponent attribute");
6650         return -1;
6651     }
6652 
6653     if (!PyInteger_Check(value)) {
6654         PyErr_Format(PyExc_TypeError, "public_exponent must be a integer, not %.200s",
6655                      Py_TYPE(value)->tp_name);
6656         return -1;
6657     }
6658 
6659     self->params.pe = PyLong_AsLong(value);
6660 
6661     return 0;
6662 }
6663 
6664 static
6665 PyGetSetDef RSAGenParams_getseters[] = {
6666     {"key_size", (getter)RSAGenParams_get_key_size,    (setter)RSAGenParams_set_key_size,
6667      "key size in bits (integer)", NULL},
6668     {"public_exponent", (getter)RSAGenParams_get_public_exponent,    (setter)RSAGenParams_set_public_exponent,
6669      "public exponent (integer)", NULL},
6670     {NULL}  /* Sentinel */
6671 };
6672 
6673 static PyMemberDef RSAGenParams_members[] = {
6674     {NULL}  /* Sentinel */
6675 };
6676 
6677 /* ============================== Class Methods ============================= */
6678 
6679 static PyMethodDef RSAGenParams_methods[] = {
6680     {NULL, NULL}  /* Sentinel */
6681 };
6682 
6683 /* =========================== Class Construction =========================== */
6684 
6685 static PyObject *
RSAGenParams_new(PyTypeObject * type,PyObject * args,PyObject * kwds)6686 RSAGenParams_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
6687 {
6688     RSAGenParams *self;
6689 
6690     TraceObjNewEnter(type);
6691 
6692     if ((self = (RSAGenParams *)type->tp_alloc(type, 0)) == NULL) {
6693         return NULL;
6694     }
6695 
6696     memset(&self->params, 0, sizeof(self->params));
6697 
6698     TraceObjNewLeave(self);
6699     return (PyObject *)self;
6700 }
6701 
6702 static void
RSAGenParams_dealloc(RSAGenParams * self)6703 RSAGenParams_dealloc(RSAGenParams* self)
6704 {
6705     TraceMethodEnter(self);
6706 
6707     Py_TYPE(self)->tp_free((PyObject*)self);
6708 }
6709 
6710 PyDoc_STRVAR(RSAGenParams_doc,
6711 "RSAGenParams(key_size=1024, public_exponent=0x10001)\n\
6712 \n\
6713 :Parameters:\n\
6714     key_size : integer\n\
6715         RSA key size in bits.\n\
6716     public_exponent : integer\n\
6717         public exponent.\n\
6718 \n\
6719 An object representing RSAGenParams.\n\
6720 ");
6721 
6722 static int
RSAGenParams_init(RSAGenParams * self,PyObject * args,PyObject * kwds)6723 RSAGenParams_init(RSAGenParams *self, PyObject *args, PyObject *kwds)
6724 {
6725     static char *kwlist[] = {"key_size", "exponent", NULL};
6726     int key_size = 1024;
6727     unsigned long public_exponent = 0x10001;
6728 
6729     TraceMethodEnter(self);
6730 
6731     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ik:RSAGenParams", kwlist,
6732                                      &key_size, &public_exponent))
6733         return -1;
6734 
6735     self->params.keySizeInBits = key_size;
6736     self->params.pe = public_exponent;
6737 
6738     return 0;
6739 }
6740 
6741 static PyObject *
RSAGenParams_str(RSAGenParams * self)6742 RSAGenParams_str(RSAGenParams *self)
6743 {
6744     TraceMethodEnter(self);
6745 
6746     return PyUnicode_FromFormat("key_size=%d public_exponent=%lu",
6747                                 self->params.keySizeInBits,
6748                                 self->params.pe);
6749 }
6750 
6751 static PyTypeObject RSAGenParamsType = {
6752     PyVarObject_HEAD_INIT(NULL, 0)
6753     "nss.nss.RSAGenParams",			/* tp_name */
6754     sizeof(RSAGenParams),			/* tp_basicsize */
6755     0,						/* tp_itemsize */
6756     (destructor)RSAGenParams_dealloc,		/* tp_dealloc */
6757     0,						/* tp_print */
6758     0,						/* tp_getattr */
6759     0,						/* tp_setattr */
6760     0,						/* tp_compare */
6761     0,						/* tp_repr */
6762     0,						/* tp_as_number */
6763     0,						/* tp_as_sequence */
6764     0,						/* tp_as_mapping */
6765     0,						/* tp_hash */
6766     0,						/* tp_call */
6767     (reprfunc)RSAGenParams_str,			/* tp_str */
6768     0,						/* tp_getattro */
6769     0,						/* tp_setattro */
6770     0,						/* tp_as_buffer */
6771     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,	/* tp_flags */
6772     RSAGenParams_doc,				/* tp_doc */
6773     (traverseproc)0,				/* tp_traverse */
6774     (inquiry)0,					/* tp_clear */
6775     0,						/* tp_richcompare */
6776     0,						/* tp_weaklistoffset */
6777     0,						/* tp_iter */
6778     0,						/* tp_iternext */
6779     RSAGenParams_methods,			/* tp_methods */
6780     RSAGenParams_members,			/* tp_members */
6781     RSAGenParams_getseters,			/* tp_getset */
6782     0,						/* tp_base */
6783     0,						/* tp_dict */
6784     0,						/* tp_descr_get */
6785     0,						/* tp_descr_set */
6786     0,						/* tp_dictoffset */
6787     (initproc)RSAGenParams_init,		/* tp_init */
6788     0,						/* tp_alloc */
6789     RSAGenParams_new,				/* tp_new */
6790 };
6791 
6792 /* ========================================================================== */
6793 /* ============================ KEYPQGParams Class ========================== */
6794 /* ========================================================================== */
6795 
6796 /* ============================ Attribute Access ============================ */
6797 
6798 static PyObject *
KEYPQGParams_get_prime(KEYPQGParams * self,void * closure)6799 KEYPQGParams_get_prime(KEYPQGParams *self, void *closure)
6800 {
6801     TraceMethodEnter(self);
6802 
6803     return SecItem_new_from_SECItem(&self->params.prime, SECITEM_unknown);
6804 }
6805 
6806 static PyObject *
KEYPQGParams_get_subprime(KEYPQGParams * self,void * closure)6807 KEYPQGParams_get_subprime(KEYPQGParams *self, void *closure)
6808 {
6809     TraceMethodEnter(self);
6810 
6811     return SecItem_new_from_SECItem(&self->params.subPrime, SECITEM_unknown);
6812 }
6813 
6814 static PyObject *
KEYPQGParams_get_base(KEYPQGParams * self,void * closure)6815 KEYPQGParams_get_base(KEYPQGParams *self, void *closure)
6816 {
6817     TraceMethodEnter(self);
6818 
6819     return SecItem_new_from_SECItem(&self->params.base, SECITEM_unknown);
6820 }
6821 
6822 static
6823 PyGetSetDef KEYPQGParams_getseters[] = {
6824     {"prime",    (getter)KEYPQGParams_get_prime,    (setter)NULL, "key prime value, also known as p", NULL},
6825     {"subprime", (getter)KEYPQGParams_get_subprime, (setter)NULL, "key subprime value, also known as q", NULL},
6826     {"base",     (getter)KEYPQGParams_get_base,     (setter)NULL, "key base value, also known as g", NULL},
6827     {NULL}  /* Sentinel */
6828 };
6829 
6830 static PyMemberDef KEYPQGParams_members[] = {
6831     {NULL}  /* Sentinel */
6832 };
6833 /* ============================== Class Methods ============================= */
6834 
6835 PyObject *
KEYPQGParams_format_lines(KEYPQGParams * self,PyObject * args,PyObject * kwds)6836 KEYPQGParams_format_lines(KEYPQGParams *self, PyObject *args, PyObject *kwds)
6837 {
6838     static char *kwlist[] = {"level", NULL};
6839     int level = 0;
6840     PyObject *lines = NULL;
6841     PyObject *obj = NULL;
6842     PyObject *obj_lines = NULL;
6843 
6844     TraceMethodEnter(self);
6845 
6846     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:format_lines", kwlist, &level))
6847         return NULL;
6848 
6849     if ((lines = PyList_New(0)) == NULL) {
6850         return NULL;
6851     }
6852 
6853 
6854     if ((obj = KEYPQGParams_get_prime(self, NULL)) == NULL) {
6855         goto fail;
6856     }
6857     FMT_SEC_INT_OBJ_APPEND_AND_CLEAR(lines, _("Prime"), obj, level, fail);
6858 
6859     if ((obj = KEYPQGParams_get_subprime(self, NULL)) == NULL) {
6860         goto fail;
6861     }
6862     FMT_SEC_INT_OBJ_APPEND_AND_CLEAR(lines, _("SubPrime"), obj, level, fail);
6863 
6864     if ((obj = KEYPQGParams_get_base(self, NULL)) == NULL) {
6865         goto fail;
6866     }
6867     FMT_SEC_INT_OBJ_APPEND_AND_CLEAR(lines, _("Base"), obj, level, fail);
6868 
6869     return lines;
6870 
6871  fail:
6872     Py_XDECREF(obj_lines);
6873     Py_XDECREF(obj);
6874     Py_XDECREF(lines);
6875     return NULL;
6876 }
6877 
6878 static PyObject *
KEYPQGParams_format(KEYPQGParams * self,PyObject * args,PyObject * kwds)6879 KEYPQGParams_format(KEYPQGParams *self, PyObject *args, PyObject *kwds)
6880 {
6881     TraceMethodEnter(self);
6882 
6883     return format_from_lines((format_lines_func)KEYPQGParams_format_lines, (PyObject *)self, args, kwds);
6884 }
6885 
6886 static PyObject *
KEYPQGParams_str(KEYPQGParams * self)6887 KEYPQGParams_str(KEYPQGParams *self)
6888 {
6889     PyObject *py_formatted_result = NULL;
6890 
6891     TraceMethodEnter(self);
6892 
6893     py_formatted_result =  KEYPQGParams_format(self, empty_tuple, NULL);
6894     return py_formatted_result;
6895 
6896 }
6897 
6898 static PyMethodDef KEYPQGParams_methods[] = {
6899     {"format_lines", (PyCFunction)KEYPQGParams_format_lines,   METH_VARARGS|METH_KEYWORDS, generic_format_lines_doc},
6900     {"format",       (PyCFunction)KEYPQGParams_format,         METH_VARARGS|METH_KEYWORDS, generic_format_doc},
6901     {NULL, NULL}  /* Sentinel */
6902 };
6903 
6904 /* =========================== Class Construction =========================== */
6905 
6906 static PyObject *
KEYPQGParams_new(PyTypeObject * type,PyObject * args,PyObject * kwds)6907 KEYPQGParams_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
6908 {
6909     KEYPQGParams *self;
6910 
6911     TraceObjNewEnter(type);
6912 
6913     if ((self = (KEYPQGParams *)type->tp_alloc(type, 0)) == NULL) {
6914         return NULL;
6915     }
6916 
6917     memset(&self->params, 0, sizeof(self->params));
6918 
6919     if ((self->params.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE)) == NULL) {
6920         type->tp_free(self);
6921         return set_nspr_error(NULL);
6922     }
6923 
6924     TraceObjNewLeave(self);
6925     return (PyObject *)self;
6926 }
6927 
6928 static void
KEYPQGParams_dealloc(KEYPQGParams * self)6929 KEYPQGParams_dealloc(KEYPQGParams* self)
6930 {
6931     TraceMethodEnter(self);
6932 
6933     if (self->params.arena) {
6934         PORT_FreeArena(self->params.arena, PR_FALSE);
6935     }
6936 
6937     Py_TYPE(self)->tp_free((PyObject*)self);
6938 }
6939 
6940 PyDoc_STRVAR(KEYPQGParams_doc,
6941 "KEYPQGParams(prime=None, subprime=None, base=None)\n\
6942 \n\
6943 :Parameters:\n\
6944     prime : SecItem or str or any buffer compatible object or None\n\
6945         prime (also known as p)\n\
6946     subprime : SecItem or str or any buffer compatible object or None\n\
6947         subprime (also known as q)\n\
6948     base : SecItem or str or any buffer compatible object or None\n\
6949         base (also known as g)\n\
6950 \n\
6951 An object representing DSA key parameters\n\
6952     - prime (also known as p)\n\
6953     - subprime (also known as q)\n\
6954     - base (also known as g)\n\
6955 \n\
6956 If no parameters are passed the default PQG the KeyPQGParams will\n\
6957 be intialized to default values. If you pass any initialization\n\
6958 parameters then they must all be passed.\n\
6959 ");
6960 
6961 static int
KEYPQGParams_init(KEYPQGParams * self,PyObject * args,PyObject * kwds)6962 KEYPQGParams_init(KEYPQGParams *self, PyObject *args, PyObject *kwds)
6963 {
6964     static char *kwlist[] = {"prime", "subprime", "base", NULL};
6965     SECItem_param *prime_param = NULL;
6966     SECItem_param *subprime_param = NULL;
6967     SECItem_param *base_param = NULL;
6968     int result = 0;
6969 
6970     TraceMethodEnter(self);
6971 
6972     // FIXME: prime, subprime & base are really large ASN.1 integers
6973     // we should accept a python int or python long and convert to a SecItem
6974 
6975     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&O&O&:KEYPQGParams", kwlist,
6976                                      SECItemOrNoneConvert, &prime_param,
6977                                      SECItemOrNoneConvert, &subprime_param,
6978                                      SECItemOrNoneConvert, &base_param))
6979         return -1;
6980 
6981     if (prime_param == NULL && subprime_param == NULL && base_param == NULL) {
6982         if ((KEYPQGParams_init_from_SECKEYPQGParams(self, &default_pqg_params)) == NULL) {
6983             result = -1;
6984             goto exit;
6985         }
6986     } else if (prime_param != NULL && subprime_param != NULL && base_param != NULL) {
6987         SECKEYPQGParams params;
6988 
6989         params.arena = NULL;
6990         params.prime = prime_param->item;
6991         params.subPrime = subprime_param->item;
6992         params.base = base_param->item;
6993 
6994         if ((KEYPQGParams_init_from_SECKEYPQGParams(self, &params)) == NULL) {
6995             result = -1;
6996             goto exit;
6997         }
6998     } else {
6999         PyErr_SetString(PyExc_ValueError, "prime, subprime and base must all be provided or none of them provided, not a mix");
7000     }
7001 
7002  exit:
7003     SECItem_param_release(prime_param);
7004     SECItem_param_release(subprime_param);
7005     SECItem_param_release(base_param);
7006     return result;
7007 }
7008 
7009 static PyTypeObject KEYPQGParamsType = {
7010     PyVarObject_HEAD_INIT(NULL, 0)
7011     "nss.nss.KEYPQGParams",			/* tp_name */
7012     sizeof(KEYPQGParams),			/* tp_basicsize */
7013     0,						/* tp_itemsize */
7014     (destructor)KEYPQGParams_dealloc,		/* tp_dealloc */
7015     0,						/* tp_print */
7016     0,						/* tp_getattr */
7017     0,						/* tp_setattr */
7018     0,						/* tp_compare */
7019     0				,		/* tp_repr */
7020     0,						/* tp_as_number */
7021     0,						/* tp_as_sequence */
7022     0,						/* tp_as_mapping */
7023     0,						/* tp_hash */
7024     0,						/* tp_call */
7025     (reprfunc)KEYPQGParams_str,			/* tp_str */
7026     0,						/* tp_getattro */
7027     0,						/* tp_setattro */
7028     0,						/* tp_as_buffer */
7029     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,	/* tp_flags */
7030     KEYPQGParams_doc,				/* tp_doc */
7031     0,						/* tp_traverse */
7032     0,						/* tp_clear */
7033     0,						/* tp_richcompare */
7034     0,						/* tp_weaklistoffset */
7035     0,						/* tp_iter */
7036     0,						/* tp_iternext */
7037     KEYPQGParams_methods,			/* tp_methods */
7038     KEYPQGParams_members,			/* tp_members */
7039     KEYPQGParams_getseters,			/* tp_getset */
7040     0,						/* tp_base */
7041     0,						/* tp_dict */
7042     0,						/* tp_descr_get */
7043     0,						/* tp_descr_set */
7044     0,						/* tp_dictoffset */
7045     (initproc)KEYPQGParams_init,		/* tp_init */
7046     0,						/* tp_alloc */
7047     KEYPQGParams_new,				/* tp_new */
7048 };
7049 
7050 PyObject *
KEYPQGParams_init_from_SECKEYPQGParams(KEYPQGParams * self,const SECKEYPQGParams * params)7051 KEYPQGParams_init_from_SECKEYPQGParams(KEYPQGParams *self, const SECKEYPQGParams *params)
7052 {
7053 
7054     SECITEM_FreeItem(&self->params.prime, PR_FALSE);
7055     if (SECITEM_CopyItem(self->params.arena, &self->params.prime, &params->prime) != SECSuccess) {
7056         return NULL;
7057     }
7058 
7059     SECITEM_FreeItem(&self->params.subPrime, PR_FALSE);
7060     if (SECITEM_CopyItem(self->params.arena, &self->params.subPrime, &params->subPrime) != SECSuccess) {
7061         return NULL;
7062     }
7063 
7064     SECITEM_FreeItem(&self->params.base, PR_FALSE);
7065     if (SECITEM_CopyItem(self->params.arena, &self->params.base, &params->base) != SECSuccess) {
7066         return NULL;
7067     }
7068 
7069 
7070     return (PyObject *) self;
7071 }
7072 
7073 PyObject *
KEYPQGParams_new_from_SECKEYPQGParams(const SECKEYPQGParams * params)7074 KEYPQGParams_new_from_SECKEYPQGParams(const SECKEYPQGParams *params)
7075 {
7076     KEYPQGParams *self = NULL;
7077 
7078     TraceObjNewEnter(NULL);
7079 
7080     if ((self = (KEYPQGParams *) KEYPQGParamsType.tp_new(&KEYPQGParamsType, NULL, NULL)) == NULL) {
7081         return NULL;
7082     }
7083 
7084     if ((KEYPQGParams_init_from_SECKEYPQGParams(self, params) == NULL)) {
7085         Py_CLEAR(self);
7086         return NULL;
7087     }
7088 
7089     TraceObjNewLeave(self);
7090     return (PyObject *) self;
7091 }
7092 
7093 /* ========================================================================== */
7094 /* =========================== RSAPublicKey Class =========================== */
7095 /* ========================================================================== */
7096 
7097 /* ============================ Attribute Access ============================ */
7098 
7099 // FIXME - shouldn these return a pyLong instead of a SecItem?
7100 // via integer_secitem_to_pylong()
7101 
7102 static PyObject *
RSAPublicKey_get_modulus(RSAPublicKey * self,void * closure)7103 RSAPublicKey_get_modulus(RSAPublicKey *self, void *closure)
7104 {
7105     TraceMethodEnter(self);
7106 
7107     Py_INCREF(self->py_modulus);
7108     return self->py_modulus;
7109 }
7110 
7111 static PyObject *
RSAPublicKey_get_exponent(RSAPublicKey * self,void * closure)7112 RSAPublicKey_get_exponent(RSAPublicKey *self, void *closure)
7113 {
7114     TraceMethodEnter(self);
7115 
7116     Py_INCREF(self->py_exponent);
7117     return self->py_exponent;
7118 }
7119 
7120 static
7121 PyGetSetDef RSAPublicKey_getseters[] = {
7122     {"modulus",  (getter)RSAPublicKey_get_modulus,  (setter)NULL, "RSA modulus", NULL},
7123     {"exponent", (getter)RSAPublicKey_get_exponent, (setter)NULL, "RSA exponent", NULL},
7124     {NULL}  /* Sentinel */
7125 };
7126 
7127 static PyMemberDef RSAPublicKey_members[] = {
7128     {NULL}  /* Sentinel */
7129 };
7130 
7131 /* ============================== Class Methods ============================= */
7132 
7133 static PyObject *
RSAPublicKey_format_lines(RSAPublicKey * self,PyObject * args,PyObject * kwds)7134 RSAPublicKey_format_lines(RSAPublicKey *self, PyObject *args, PyObject *kwds)
7135 {
7136     static char *kwlist[] = {"level", NULL};
7137     int level = 0;
7138     PyObject *lines = NULL;
7139     PyObject *obj = NULL;
7140 
7141     TraceMethodEnter(self);
7142 
7143     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:format_lines", kwlist, &level))
7144         return NULL;
7145 
7146     if ((lines = PyList_New(0)) == NULL) {
7147         return NULL;
7148     }
7149 
7150     if ((obj = RSAPublicKey_get_modulus(self, NULL)) == NULL) {
7151         goto fail;
7152     }
7153     FMT_SEC_INT_OBJ_APPEND_AND_CLEAR(lines, _("Modulus"), obj, level, fail);
7154 
7155     if ((obj = RSAPublicKey_get_exponent(self, NULL)) == NULL) {
7156         goto fail;
7157     }
7158     FMT_SEC_INT_OBJ_APPEND_AND_CLEAR(lines, _("Exponent"), obj, level, fail);
7159 
7160     return lines;
7161  fail:
7162     Py_XDECREF(obj);
7163     Py_XDECREF(lines);
7164     return NULL;
7165 }
7166 
7167 static PyObject *
RSAPublicKey_format(RSAPublicKey * self,PyObject * args,PyObject * kwds)7168 RSAPublicKey_format(RSAPublicKey *self, PyObject *args, PyObject *kwds)
7169 {
7170     TraceMethodEnter(self);
7171 
7172     return format_from_lines((format_lines_func)RSAPublicKey_format_lines, (PyObject *)self, args, kwds);
7173 }
7174 
7175 static PyObject *
RSAPublicKey_str(RSAPublicKey * self)7176 RSAPublicKey_str(RSAPublicKey *self)
7177 {
7178     PyObject *py_formatted_result = NULL;
7179 
7180     TraceMethodEnter(self);
7181 
7182     py_formatted_result =  RSAPublicKey_format(self, empty_tuple, NULL);
7183     return py_formatted_result;
7184 
7185 }
7186 
7187 static PyMethodDef RSAPublicKey_methods[] = {
7188     {"format_lines", (PyCFunction)RSAPublicKey_format_lines,   METH_VARARGS|METH_KEYWORDS, generic_format_lines_doc},
7189     {"format",       (PyCFunction)RSAPublicKey_format,         METH_VARARGS|METH_KEYWORDS, generic_format_doc},
7190     {NULL, NULL}  /* Sentinel */
7191 };
7192 
7193 /* =========================== Class Construction =========================== */
7194 
7195 static PyObject *
RSAPublicKey_new(PyTypeObject * type,PyObject * args,PyObject * kwds)7196 RSAPublicKey_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
7197 {
7198     RSAPublicKey *self;
7199 
7200     TraceObjNewEnter(type);
7201 
7202     if ((self = (RSAPublicKey *)type->tp_alloc(type, 0)) == NULL) {
7203         return NULL;
7204     }
7205 
7206     self->py_modulus = NULL;
7207     self->py_exponent = NULL;
7208 
7209     TraceObjNewLeave(self);
7210     return (PyObject *)self;
7211 }
7212 
7213 static int
RSAPublicKey_traverse(RSAPublicKey * self,visitproc visit,void * arg)7214 RSAPublicKey_traverse(RSAPublicKey *self, visitproc visit, void *arg)
7215 {
7216     TraceMethodEnter(self);
7217 
7218     Py_VISIT(self->py_modulus);
7219     Py_VISIT(self->py_exponent);
7220     return 0;
7221 }
7222 
7223 static int
RSAPublicKey_clear(RSAPublicKey * self)7224 RSAPublicKey_clear(RSAPublicKey* self)
7225 {
7226     TraceMethodEnter(self);
7227 
7228     Py_CLEAR(self->py_modulus);
7229     Py_CLEAR(self->py_exponent);
7230     return 0;
7231 }
7232 
7233 static void
RSAPublicKey_dealloc(RSAPublicKey * self)7234 RSAPublicKey_dealloc(RSAPublicKey* self)
7235 {
7236     TraceMethodEnter(self);
7237 
7238     RSAPublicKey_clear(self);
7239     Py_TYPE(self)->tp_free((PyObject*)self);
7240 }
7241 
7242 PyDoc_STRVAR(RSAPublicKey_doc,
7243 "An object representing an RSA Public Key");
7244 
7245 static int
RSAPublicKey_init(RSAPublicKey * self,PyObject * args,PyObject * kwds)7246 RSAPublicKey_init(RSAPublicKey *self, PyObject *args, PyObject *kwds)
7247 {
7248     TraceMethodEnter(self);
7249 
7250     return 0;
7251 }
7252 
7253 static PyTypeObject RSAPublicKeyType = {
7254     PyVarObject_HEAD_INIT(NULL, 0)
7255     "nss.nss.RSAPublicKey",			/* tp_name */
7256     sizeof(RSAPublicKey),			/* tp_basicsize */
7257     0,						/* tp_itemsize */
7258     (destructor)RSAPublicKey_dealloc,		/* tp_dealloc */
7259     0,						/* tp_print */
7260     0,						/* tp_getattr */
7261     0,						/* tp_setattr */
7262     0,						/* tp_compare */
7263     0,						/* tp_repr */
7264     0,						/* tp_as_number */
7265     0,						/* tp_as_sequence */
7266     0,						/* tp_as_mapping */
7267     0,						/* tp_hash */
7268     0,						/* tp_call */
7269     (reprfunc)RSAPublicKey_str,			/* tp_str */
7270     0,						/* tp_getattro */
7271     0,						/* tp_setattro */
7272     0,						/* tp_as_buffer */
7273     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,	/* tp_flags */
7274     RSAPublicKey_doc,				/* tp_doc */
7275     (traverseproc)RSAPublicKey_traverse,	/* tp_traverse */
7276     (inquiry)RSAPublicKey_clear,		/* tp_clear */
7277     0,						/* tp_richcompare */
7278     0,						/* tp_weaklistoffset */
7279     0,						/* tp_iter */
7280     0,						/* tp_iternext */
7281     RSAPublicKey_methods,			/* tp_methods */
7282     RSAPublicKey_members,			/* tp_members */
7283     RSAPublicKey_getseters,			/* tp_getset */
7284     0,						/* tp_base */
7285     0,						/* tp_dict */
7286     0,						/* tp_descr_get */
7287     0,						/* tp_descr_set */
7288     0,						/* tp_dictoffset */
7289     (initproc)RSAPublicKey_init,		/* tp_init */
7290     0,						/* tp_alloc */
7291     RSAPublicKey_new,				/* tp_new */
7292 };
7293 
7294 PyObject *
RSAPublicKey_new_from_SECKEYRSAPublicKey(SECKEYRSAPublicKey * rsa)7295 RSAPublicKey_new_from_SECKEYRSAPublicKey(SECKEYRSAPublicKey *rsa)
7296 {
7297     RSAPublicKey *self = NULL;
7298 
7299     TraceObjNewEnter(NULL);
7300 
7301     if ((self = (RSAPublicKey *) RSAPublicKeyType.tp_new(&RSAPublicKeyType, NULL, NULL)) == NULL) {
7302         return NULL;
7303     }
7304 
7305     if ((self->py_modulus = SecItem_new_from_SECItem(&rsa->modulus, SECITEM_unknown)) == NULL) {
7306         Py_CLEAR(self);
7307         return NULL;
7308     }
7309 
7310     if ((self->py_exponent = SecItem_new_from_SECItem(&rsa->publicExponent, SECITEM_unknown)) == NULL) {
7311         Py_CLEAR(self);
7312         return NULL;
7313     }
7314 
7315     TraceObjNewLeave(self);
7316     return (PyObject *) self;
7317 }
7318 
7319 /* ========================================================================== */
7320 /* =========================== DSAPublicKey Class =========================== */
7321 /* ========================================================================== */
7322 
7323 /* ============================ Attribute Access ============================ */
7324 
7325 static PyObject *
DSAPublicKey_get_pqg_params(DSAPublicKey * self,void * closure)7326 DSAPublicKey_get_pqg_params(DSAPublicKey *self, void *closure)
7327 {
7328     TraceMethodEnter(self);
7329 
7330     Py_INCREF(self->py_pqg_params);
7331     return self->py_pqg_params;
7332 }
7333 
7334 static PyObject *
DSAPublicKey_get_public_value(DSAPublicKey * self,void * closure)7335 DSAPublicKey_get_public_value(DSAPublicKey *self, void *closure)
7336 {
7337     TraceMethodEnter(self);
7338 
7339     Py_INCREF(self->py_public_value);
7340     return self->py_public_value;
7341 }
7342 
7343 static
7344 PyGetSetDef DSAPublicKey_getseters[] = {
7345     {"pqg_params",   (getter)DSAPublicKey_get_pqg_params,   (setter)NULL, "DSA P,Q,G params as a KEYPQGParams object", NULL},
7346     {"public_value", (getter)DSAPublicKey_get_public_value, (setter)NULL, "DSA public_value", NULL},
7347     {NULL}  /* Sentinel */
7348 };
7349 
7350 static PyMemberDef DSAPublicKey_members[] = {
7351     {NULL}  /* Sentinel */
7352 };
7353 
7354 /* ============================== Class Methods ============================= */
7355 
7356 static PyObject *
DSAPublicKey_format_lines(DSAPublicKey * self,PyObject * args,PyObject * kwds)7357 DSAPublicKey_format_lines(DSAPublicKey *self, PyObject *args, PyObject *kwds)
7358 {
7359     static char *kwlist[] = {"level", NULL};
7360     int level = 0;
7361     PyObject *lines = NULL;
7362     PyObject *obj = NULL;
7363     PyObject *exponent = NULL;
7364 
7365     TraceMethodEnter(self);
7366 
7367     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:format_lines", kwlist, &level))
7368         return NULL;
7369 
7370     if ((lines = PyList_New(0)) == NULL) {
7371         return NULL;
7372     }
7373 
7374     if ((obj = DSAPublicKey_get_pqg_params(self, NULL)) == NULL) {
7375         goto fail;
7376     }
7377     CALL_FORMAT_LINES_AND_APPEND(lines, obj, level, fail);
7378     Py_CLEAR(obj);
7379 
7380     if ((obj = DSAPublicKey_get_public_value(self, NULL)) == NULL) {
7381         goto fail;
7382     }
7383     FMT_SEC_INT_OBJ_APPEND_AND_CLEAR(lines, _("Public Value"), obj, level, fail);
7384     return lines;
7385  fail:
7386     Py_XDECREF(obj);
7387     Py_XDECREF(exponent);
7388     Py_XDECREF(lines);
7389     return NULL;
7390 }
7391 
7392 static PyObject *
DSAPublicKey_format(DSAPublicKey * self,PyObject * args,PyObject * kwds)7393 DSAPublicKey_format(DSAPublicKey *self, PyObject *args, PyObject *kwds)
7394 {
7395     TraceMethodEnter(self);
7396 
7397     return format_from_lines((format_lines_func)DSAPublicKey_format_lines, (PyObject *)self, args, kwds);
7398 }
7399 
7400 static PyObject *
DSAPublicKey_str(DSAPublicKey * self)7401 DSAPublicKey_str(DSAPublicKey *self)
7402 {
7403     PyObject *py_formatted_result = NULL;
7404 
7405     TraceMethodEnter(self);
7406 
7407     py_formatted_result =  DSAPublicKey_format(self, empty_tuple, NULL);
7408     return py_formatted_result;
7409 
7410 }
7411 
7412 static PyMethodDef DSAPublicKey_methods[] = {
7413     {"format_lines", (PyCFunction)DSAPublicKey_format_lines,   METH_VARARGS|METH_KEYWORDS, generic_format_lines_doc},
7414     {"format",       (PyCFunction)DSAPublicKey_format,         METH_VARARGS|METH_KEYWORDS, generic_format_doc},
7415     {NULL, NULL}  /* Sentinel */
7416 };
7417 
7418 /* =========================== Class Construction =========================== */
7419 
7420 static PyObject *
DSAPublicKey_new(PyTypeObject * type,PyObject * args,PyObject * kwds)7421 DSAPublicKey_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
7422 {
7423     DSAPublicKey *self;
7424 
7425     TraceObjNewEnter(type);
7426 
7427     if ((self = (DSAPublicKey *)type->tp_alloc(type, 0)) == NULL) {
7428         return NULL;
7429     }
7430 
7431     self->py_pqg_params = NULL;
7432     self->py_public_value = NULL;
7433 
7434     TraceObjNewLeave(self);
7435     return (PyObject *)self;
7436 }
7437 
7438 static int
DSAPublicKey_traverse(DSAPublicKey * self,visitproc visit,void * arg)7439 DSAPublicKey_traverse(DSAPublicKey *self, visitproc visit, void *arg)
7440 {
7441     TraceMethodEnter(self);
7442 
7443     Py_VISIT(self->py_pqg_params);
7444     Py_VISIT(self->py_public_value);
7445     return 0;
7446 }
7447 
7448 static int
DSAPublicKey_clear(DSAPublicKey * self)7449 DSAPublicKey_clear(DSAPublicKey* self)
7450 {
7451     TraceMethodEnter(self);
7452 
7453     Py_CLEAR(self->py_pqg_params);
7454     Py_CLEAR(self->py_public_value);
7455     return 0;
7456 }
7457 
7458 static void
DSAPublicKey_dealloc(DSAPublicKey * self)7459 DSAPublicKey_dealloc(DSAPublicKey* self)
7460 {
7461     TraceMethodEnter(self);
7462 
7463     DSAPublicKey_clear(self);
7464     Py_TYPE(self)->tp_free((PyObject*)self);
7465 }
7466 
7467 PyDoc_STRVAR(DSAPublicKey_doc,
7468 "A object representing a DSA Public Key");
7469 
7470 static int
DSAPublicKey_init(DSAPublicKey * self,PyObject * args,PyObject * kwds)7471 DSAPublicKey_init(DSAPublicKey *self, PyObject *args, PyObject *kwds)
7472 {
7473     TraceMethodEnter(self);
7474 
7475     return 0;
7476 }
7477 
7478 static PyTypeObject DSAPublicKeyType = {
7479     PyVarObject_HEAD_INIT(NULL, 0)
7480     "nss.nss.DSAPublicKey",			/* tp_name */
7481     sizeof(DSAPublicKey),			/* tp_basicsize */
7482     0,						/* tp_itemsize */
7483     (destructor)DSAPublicKey_dealloc,		/* tp_dealloc */
7484     0,						/* tp_print */
7485     0,						/* tp_getattr */
7486     0,						/* tp_setattr */
7487     0,						/* tp_compare */
7488     0,						/* tp_repr */
7489     0,						/* tp_as_number */
7490     0,						/* tp_as_sequence */
7491     0,						/* tp_as_mapping */
7492     0,						/* tp_hash */
7493     0,						/* tp_call */
7494     (reprfunc)DSAPublicKey_str,			/* tp_str */
7495     0,						/* tp_getattro */
7496     0,						/* tp_setattro */
7497     0,						/* tp_as_buffer */
7498     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,	/* tp_flags */
7499     DSAPublicKey_doc,				/* tp_doc */
7500     (traverseproc)DSAPublicKey_traverse,	/* tp_traverse */
7501     (inquiry)DSAPublicKey_clear,		/* tp_clear */
7502     0,						/* tp_richcompare */
7503     0,						/* tp_weaklistoffset */
7504     0,						/* tp_iter */
7505     0,						/* tp_iternext */
7506     DSAPublicKey_methods,			/* tp_methods */
7507     DSAPublicKey_members,			/* tp_members */
7508     DSAPublicKey_getseters,			/* tp_getset */
7509     0,						/* tp_base */
7510     0,						/* tp_dict */
7511     0,						/* tp_descr_get */
7512     0,						/* tp_descr_set */
7513     0,						/* tp_dictoffset */
7514     (initproc)DSAPublicKey_init,		/* tp_init */
7515     0,						/* tp_alloc */
7516     DSAPublicKey_new,				/* tp_new */
7517 };
7518 
7519 PyObject *
DSAPublicKey_new_from_SECKEYDSAPublicKey(SECKEYDSAPublicKey * dsa)7520 DSAPublicKey_new_from_SECKEYDSAPublicKey(SECKEYDSAPublicKey *dsa)
7521 {
7522     DSAPublicKey *self = NULL;
7523 
7524     TraceObjNewEnter(NULL);
7525 
7526     if ((self = (DSAPublicKey *) DSAPublicKeyType.tp_new(&DSAPublicKeyType, NULL, NULL)) == NULL) {
7527         return NULL;
7528     }
7529 
7530     if ((self->py_pqg_params = KEYPQGParams_new_from_SECKEYPQGParams(&dsa->params)) == NULL) {
7531         Py_CLEAR(self);
7532         return NULL;
7533     }
7534 
7535     if ((self->py_public_value = SecItem_new_from_SECItem(&dsa->publicValue, SECITEM_unknown)) == NULL) {
7536         Py_CLEAR(self);
7537         return NULL;
7538     }
7539 
7540     TraceObjNewLeave(self);
7541     return (PyObject *) self;
7542 }
7543 
7544 /* ========================================================================== */
7545 /* ============================= SignedData Class =========================== */
7546 /* ========================================================================== */
7547 
7548 /* ============================ Attribute Access ============================ */
7549 
7550 static PyObject *
SignedData_get_der(SignedData * self,void * closure)7551 SignedData_get_der(SignedData *self, void *closure)
7552 {
7553     TraceMethodEnter(self);
7554 
7555     Py_INCREF(self->py_der);
7556     return self->py_der;
7557 }
7558 
7559 static PyObject *
SignedData_get_data(SignedData * self,void * closure)7560 SignedData_get_data(SignedData *self, void *closure)
7561 {
7562     TraceMethodEnter(self);
7563 
7564     Py_INCREF(self->py_data);
7565     return self->py_data;
7566 }
7567 
7568 static PyObject *
SignedData_get_algorithm(SignedData * self,void * closure)7569 SignedData_get_algorithm(SignedData *self, void *closure)
7570 {
7571     TraceMethodEnter(self);
7572 
7573     Py_INCREF(self->py_algorithm);
7574     return self->py_algorithm;
7575 }
7576 
7577 static PyObject *
SignedData_get_signature(SignedData * self,void * closure)7578 SignedData_get_signature(SignedData *self, void *closure)
7579 {
7580     TraceMethodEnter(self);
7581 
7582     Py_INCREF(self->py_signature);
7583     return self->py_signature;
7584 }
7585 
7586 static
7587 PyGetSetDef SignedData_getseters[] = {
7588     {"der",        (getter)SignedData_get_der,        (setter)NULL, "original der encoded ASN1 signed data as a SecItem object", NULL},
7589     {"data",       (getter)SignedData_get_data,       (setter)NULL, "signed data as a SecItem object", NULL},
7590     {"algorithm",  (getter)SignedData_get_algorithm,  (setter)NULL, "signature algorithm as a AlgorithmID object", NULL},
7591     {"signature",  (getter)SignedData_get_signature,  (setter)NULL, "signature as a SecItem object", NULL},
7592     {NULL}  /* Sentinel */
7593 };
7594 
7595 static PyMemberDef SignedData_members[] = {
7596     {NULL}  /* Sentinel */
7597 };
7598 
7599 /* ============================== Class Methods ============================= */
7600 
7601 static PyObject *
SignedData_format_lines(SignedData * self,PyObject * args,PyObject * kwds)7602 SignedData_format_lines(SignedData *self, PyObject *args, PyObject *kwds)
7603 {
7604     static char *kwlist[] = {"level", NULL};
7605     int level = 0;
7606     PyObject *lines = NULL;
7607     PyObject *obj = NULL;
7608 
7609     TraceMethodEnter(self);
7610 
7611     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:format_lines", kwlist, &level))
7612         return NULL;
7613 
7614     if ((lines = PyList_New(0)) == NULL) {
7615         return NULL;
7616     }
7617 
7618     if ((obj = SignedData_get_algorithm(self, NULL)) == NULL) {
7619         goto fail;
7620     }
7621     FMT_LABEL_AND_APPEND(lines, _("Signature Algorithm"), level, fail);
7622     CALL_FORMAT_LINES_AND_APPEND(lines, obj, level+1, fail);
7623     Py_CLEAR(obj);
7624 
7625     FMT_LABEL_AND_APPEND(lines, _("Signature"), level, fail);
7626 
7627     if ((obj = SignedData_get_signature(self, NULL)) == NULL) {
7628         goto fail;
7629     }
7630     APPEND_OBJ_TO_HEX_LINES_AND_CLEAR(lines, obj, level+1, fail);
7631 
7632     obj = fingerprint_format_lines(&((SecItem *)self->py_der)->item, level);
7633     APPEND_LINE_TUPLES_AND_CLEAR(lines, obj, fail);
7634 
7635     return lines;
7636 
7637  fail:
7638     Py_XDECREF(obj);
7639     Py_XDECREF(lines);
7640     return NULL;
7641 }
7642 
7643 static PyObject *
SignedData_format(SignedData * self,PyObject * args,PyObject * kwds)7644 SignedData_format(SignedData *self, PyObject *args, PyObject *kwds)
7645 {
7646     TraceMethodEnter(self);
7647 
7648     return format_from_lines((format_lines_func)SignedData_format_lines, (PyObject *)self, args, kwds);
7649 }
7650 
7651 static PyObject *
SignedData_str(SignedData * self)7652 SignedData_str(SignedData *self)
7653 {
7654     PyObject *py_formatted_result = NULL;
7655 
7656     py_formatted_result =  SignedData_format(self, empty_tuple, NULL);
7657     return py_formatted_result;
7658 
7659 }
7660 
7661 static PyMethodDef SignedData_methods[] = {
7662     {"format_lines", (PyCFunction)SignedData_format_lines,   METH_VARARGS|METH_KEYWORDS, generic_format_lines_doc},
7663     {"format",       (PyCFunction)SignedData_format,         METH_VARARGS|METH_KEYWORDS, generic_format_doc},
7664     {NULL, NULL}  /* Sentinel */
7665 };
7666 
7667 /* =========================== Class Construction =========================== */
7668 
7669 static PyObject *
SignedData_new(PyTypeObject * type,PyObject * args,PyObject * kwds)7670 SignedData_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
7671 {
7672     SignedData *self;
7673 
7674     TraceObjNewEnter(type);
7675 
7676     if ((self = (SignedData *)type->tp_alloc(type, 0)) == NULL) {
7677         return NULL;
7678     }
7679 
7680     self->py_der = NULL;
7681     self->py_data = NULL;
7682     self->py_algorithm = NULL;
7683     self->py_signature = NULL;
7684 
7685     if ((self->arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE)) == NULL ) {
7686         type->tp_free(self);
7687         return set_nspr_error(NULL);
7688     }
7689 
7690     memset(&self->signed_data, 0, sizeof(self->signed_data));
7691 
7692     TraceObjNewLeave(self);
7693     return (PyObject *)self;
7694 }
7695 
7696 static int
SignedData_traverse(SignedData * self,visitproc visit,void * arg)7697 SignedData_traverse(SignedData *self, visitproc visit, void *arg)
7698 {
7699     TraceMethodEnter(self);
7700 
7701     Py_VISIT(self->py_der);
7702     Py_VISIT(self->py_data);
7703     Py_VISIT(self->py_algorithm);
7704     Py_VISIT(self->py_signature);
7705     return 0;
7706 }
7707 
7708 static int
SignedData_clear(SignedData * self)7709 SignedData_clear(SignedData* self)
7710 {
7711     TraceMethodEnter(self);
7712 
7713     Py_CLEAR(self->py_der);
7714     Py_CLEAR(self->py_data);
7715     Py_CLEAR(self->py_algorithm);
7716     Py_CLEAR(self->py_signature);
7717     return 0;
7718 }
7719 
7720 static void
SignedData_dealloc(SignedData * self)7721 SignedData_dealloc(SignedData* self)
7722 {
7723     TraceMethodEnter(self);
7724 
7725     SignedData_clear(self);
7726     PORT_FreeArena(self->arena, PR_FALSE);
7727     Py_TYPE(self)->tp_free((PyObject*)self);
7728 }
7729 
7730 PyDoc_STRVAR(SignedData_doc,
7731 "A object representing a signature");
7732 
7733 static int
SignedData_init(SignedData * self,PyObject * args,PyObject * kwds)7734 SignedData_init(SignedData *self, PyObject *args, PyObject *kwds)
7735 {
7736     TraceMethodEnter(self);
7737 
7738     return 0;
7739 }
7740 
7741 static PyTypeObject SignedDataType = {
7742     PyVarObject_HEAD_INIT(NULL, 0)
7743     "nss.nss.SignedData",			/* tp_name */
7744     sizeof(SignedData),				/* tp_basicsize */
7745     0,						/* tp_itemsize */
7746     (destructor)SignedData_dealloc,		/* tp_dealloc */
7747     0,						/* tp_print */
7748     0,						/* tp_getattr */
7749     0,						/* tp_setattr */
7750     0,						/* tp_compare */
7751     0,						/* tp_repr */
7752     0,						/* tp_as_number */
7753     0,						/* tp_as_sequence */
7754     0,						/* tp_as_mapping */
7755     0,						/* tp_hash */
7756     0,						/* tp_call */
7757     (reprfunc)SignedData_str,			/* tp_str */
7758     0,						/* tp_getattro */
7759     0,						/* tp_setattro */
7760     0,						/* tp_as_buffer */
7761     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,	/* tp_flags */
7762     SignedData_doc,				/* tp_doc */
7763     (traverseproc)SignedData_traverse,		/* tp_traverse */
7764     (inquiry)SignedData_clear,			/* tp_clear */
7765     0,						/* tp_richcompare */
7766     0,						/* tp_weaklistoffset */
7767     0,						/* tp_iter */
7768     0,						/* tp_iternext */
7769     SignedData_methods,				/* tp_methods */
7770     SignedData_members,				/* tp_members */
7771     SignedData_getseters,			/* tp_getset */
7772     0,						/* tp_base */
7773     0,						/* tp_dict */
7774     0,						/* tp_descr_get */
7775     0,						/* tp_descr_set */
7776     0,						/* tp_dictoffset */
7777     (initproc)SignedData_init,			/* tp_init */
7778     0,						/* tp_alloc */
7779     SignedData_new,				/* tp_new */
7780 };
7781 
7782 PyObject *
SignedData_new_from_SECItem(SECItem * item)7783 SignedData_new_from_SECItem(SECItem *item)
7784 {
7785     SignedData *self = NULL;
7786 
7787     TraceObjNewEnter(NULL);
7788 
7789     if ((self = (SignedData *) SignedDataType.tp_new(&SignedDataType, NULL, NULL)) == NULL) {
7790         return NULL;
7791     }
7792 
7793     if (SEC_ASN1DecodeItem(self->arena, &self->signed_data,
7794                            SEC_ASN1_GET(CERT_SignedDataTemplate), item) != SECSuccess) {
7795         set_nspr_error("cannot decode DER encoded signed data");
7796         Py_CLEAR(self);
7797         return NULL;
7798     }
7799 
7800     if ((self->py_der =
7801          SecItem_new_from_SECItem(item, SECITEM_signed_data)) == NULL) {
7802         Py_CLEAR(self);
7803         return NULL;
7804     }
7805 
7806     if ((self->py_data =
7807          SecItem_new_from_SECItem(&self->signed_data.data, SECITEM_unknown)) == NULL) {
7808         Py_CLEAR(self);
7809         return NULL;
7810     }
7811 
7812     if ((self->py_algorithm =
7813          AlgorithmID_new_from_SECAlgorithmID(&self->signed_data.signatureAlgorithm)) == NULL) {
7814         Py_CLEAR(self);
7815         return NULL;
7816     }
7817 
7818     DER_ConvertBitString(&self->signed_data.signature);
7819     if ((self->py_signature =
7820          SecItem_new_from_SECItem(&self->signed_data.signature, SECITEM_signature)) == NULL) {
7821         Py_CLEAR(self);
7822         return NULL;
7823     }
7824 
7825     TraceObjNewLeave(self);
7826     return (PyObject *) self;
7827 }
7828 
7829 /* ========================================================================== */
7830 /* ============================= PublicKey Class ============================ */
7831 /* ========================================================================== */
7832 
7833 /* ============================ Attribute Access ============================ */
7834 
7835 static PyObject *
PublicKey_get_key_type(PublicKey * self,void * closure)7836 PublicKey_get_key_type(PublicKey *self, void *closure)
7837 {
7838     TraceMethodEnter(self);
7839 
7840     return PyLong_FromLong(self->pk->keyType);
7841 }
7842 
7843 static PyObject *
PublicKey_get_key_type_str(PublicKey * self,void * closure)7844 PublicKey_get_key_type_str(PublicKey *self, void *closure)
7845 {
7846     TraceMethodEnter(self);
7847 
7848     return PyUnicode_FromString(key_type_str(self->pk->keyType));
7849 }
7850 
7851 static PyObject *
PublicKey_get_rsa(PublicKey * self,void * closure)7852 PublicKey_get_rsa(PublicKey *self, void *closure)
7853 {
7854     TraceMethodEnter(self);
7855 
7856     if (self->pk->keyType == rsaKey) {
7857         Py_INCREF(self->py_rsa_key);
7858         return self->py_rsa_key;
7859     } else {
7860         PyErr_Format(PyExc_AttributeError, "when '%.50s' object has key_type=%s there is no attribute 'rsa'",
7861                      Py_TYPE(self)->tp_name, key_type_str(self->pk->keyType));
7862         return NULL;
7863     }
7864 }
7865 
7866 static PyObject *
PublicKey_get_dsa(PublicKey * self,void * closure)7867 PublicKey_get_dsa(PublicKey *self, void *closure)
7868 {
7869     TraceMethodEnter(self);
7870 
7871     if (self->pk->keyType == dsaKey) {
7872         Py_INCREF(self->py_dsa_key);
7873         return self->py_dsa_key;
7874     } else {
7875         PyErr_Format(PyExc_AttributeError, "when '%.50s' object has key_type=%s there is no attribute 'dsa'",
7876                      Py_TYPE(self)->tp_name, key_type_str(self->pk->keyType));
7877         return NULL;
7878     }
7879 }
7880 
7881 static
7882 PyGetSetDef PublicKey_getseters[] = {
7883     {"key_type",     (getter)PublicKey_get_key_type,     (setter)NULL, "key type (e.g. rsaKey, dsaKey, etc.) as an int", NULL},
7884     {"key_type_str", (getter)PublicKey_get_key_type_str, (setter)NULL, "key type as a string", NULL},
7885     {"rsa",          (getter)PublicKey_get_rsa,          (setter)NULL, "RSA key as a RSAPublicKey object", NULL},
7886     {"dsa",          (getter)PublicKey_get_dsa,          (setter)NULL, "RSA key as a RSAPublicKey object", NULL},
7887     {NULL}  /* Sentinel */
7888 };
7889 
7890 static PyMemberDef PublicKey_members[] = {
7891     {NULL}  /* Sentinel */
7892 };
7893 
7894 /* ============================== Class Methods ============================= */
7895 
7896 static PyObject *
PublicKey_format_lines(PublicKey * self,PyObject * args,PyObject * kwds)7897 PublicKey_format_lines(PublicKey *self, PyObject *args, PyObject *kwds)
7898 {
7899     static char *kwlist[] = {"level", NULL};
7900     int level = 0;
7901     PyObject *lines = NULL;
7902     PyObject *obj = NULL;
7903     PyObject *py_key = NULL;
7904 
7905     TraceMethodEnter(self);
7906 
7907     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:format_lines", kwlist, &level))
7908         return NULL;
7909 
7910     if ((lines = PyList_New(0)) == NULL) {
7911         goto fail;
7912     }
7913 
7914     switch(self->pk->keyType) {       /* FIXME: handle the other cases */
7915     case rsaKey:
7916         FMT_LABEL_AND_APPEND(lines, _("RSA Public Key"), level, fail);
7917         CALL_FORMAT_LINES_AND_APPEND(lines, self->py_rsa_key, level+1, fail);
7918         break;
7919     case dsaKey:
7920         FMT_LABEL_AND_APPEND(lines, _("DSA Public Key"), level, fail);
7921         CALL_FORMAT_LINES_AND_APPEND(lines, self->py_dsa_key, level+1, fail);
7922         break;
7923     case fortezzaKey:
7924     case dhKey:
7925     case keaKey:
7926     case ecKey:
7927     case rsaPssKey:
7928     case rsaOaepKey:
7929     case nullKey:
7930         if ((obj = PublicKey_get_key_type_str(self, NULL)) == NULL) {
7931             goto fail;
7932         }
7933         FMT_OBJ_AND_APPEND(lines, _("Key Type"), obj, level, fail);
7934         Py_CLEAR(obj);
7935         break;
7936     }
7937 
7938     return lines;
7939 
7940  fail:
7941     Py_XDECREF(lines);
7942     Py_XDECREF(obj);
7943     Py_XDECREF(py_key);
7944     return NULL;
7945 }
7946 
7947 static PyObject *
PublicKey_format(PublicKey * self,PyObject * args,PyObject * kwds)7948 PublicKey_format(PublicKey *self, PyObject *args, PyObject *kwds)
7949 {
7950     TraceMethodEnter(self);
7951 
7952     return format_from_lines((format_lines_func)PublicKey_format_lines, (PyObject *)self, args, kwds);
7953 }
7954 
7955 static PyObject *
PublicKey_str(PublicKey * self)7956 PublicKey_str(PublicKey *self)
7957 {
7958     PyObject *py_formatted_result = NULL;
7959 
7960     py_formatted_result = PublicKey_format(self, empty_tuple, NULL);
7961     return py_formatted_result;
7962 
7963 }
7964 
7965 static PyMethodDef PublicKey_methods[] = {
7966     {"format_lines", (PyCFunction)PublicKey_format_lines,   METH_VARARGS|METH_KEYWORDS, generic_format_lines_doc},
7967     {"format",       (PyCFunction)PublicKey_format,         METH_VARARGS|METH_KEYWORDS, generic_format_doc},
7968     {NULL, NULL}  /* Sentinel */
7969 };
7970 
7971 /* =========================== Class Construction =========================== */
7972 
7973 static PyObject *
PublicKey_new(PyTypeObject * type,PyObject * args,PyObject * kwds)7974 PublicKey_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
7975 {
7976     PublicKey *self;
7977 
7978     TraceObjNewEnter(type);
7979 
7980     if ((self = (PublicKey *)type->tp_alloc(type, 0)) == NULL) {
7981         return NULL;
7982     }
7983 
7984     self->py_rsa_key = NULL;
7985     self->py_dsa_key = NULL;
7986 
7987     memset(&self->pk, 0, sizeof(self->pk));
7988 
7989     TraceObjNewLeave(self);
7990     return (PyObject *)self;
7991 }
7992 
7993 static int
PublicKey_traverse(PublicKey * self,visitproc visit,void * arg)7994 PublicKey_traverse(PublicKey *self, visitproc visit, void *arg)
7995 {
7996     TraceMethodEnter(self);
7997 
7998     Py_VISIT(self->py_rsa_key);
7999     Py_VISIT(self->py_dsa_key);
8000     return 0;
8001 }
8002 
8003 static int
PublicKey_clear(PublicKey * self)8004 PublicKey_clear(PublicKey* self)
8005 {
8006     TraceMethodEnter(self);
8007 
8008     Py_CLEAR(self->py_rsa_key);
8009     Py_CLEAR(self->py_dsa_key);
8010     return 0;
8011 }
8012 
8013 static void
PublicKey_dealloc(PublicKey * self)8014 PublicKey_dealloc(PublicKey* self)
8015 {
8016     TraceMethodEnter(self);
8017 
8018     PublicKey_clear(self);
8019     SECKEY_DestroyPublicKey(self->pk);
8020     Py_TYPE(self)->tp_free((PyObject*)self);
8021 }
8022 
8023 PyDoc_STRVAR(PublicKey_doc,
8024 "An object representing a Public Key");
8025 
8026 static int
PublicKey_init(PublicKey * self,PyObject * args,PyObject * kwds)8027 PublicKey_init(PublicKey *self, PyObject *args, PyObject *kwds)
8028 {
8029     TraceMethodEnter(self);
8030 
8031     return 0;
8032 }
8033 
8034 static PyTypeObject PublicKeyType = {
8035     PyVarObject_HEAD_INIT(NULL, 0)
8036     "nss.nss.PublicKey",			/* tp_name */
8037     sizeof(PublicKey),				/* tp_basicsize */
8038     0,						/* tp_itemsize */
8039     (destructor)PublicKey_dealloc,		/* tp_dealloc */
8040     0,						/* tp_print */
8041     0,						/* tp_getattr */
8042     0,						/* tp_setattr */
8043     0,						/* tp_compare */
8044     0,						/* tp_repr */
8045     0,						/* tp_as_number */
8046     0,						/* tp_as_sequence */
8047     0,						/* tp_as_mapping */
8048     0,						/* tp_hash */
8049     0,						/* tp_call */
8050     (reprfunc)PublicKey_str,			/* tp_str */
8051     0,						/* tp_getattro */
8052     0,						/* tp_setattro */
8053     0,						/* tp_as_buffer */
8054     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,	/* tp_flags */
8055     PublicKey_doc,				/* tp_doc */
8056     (traverseproc)PublicKey_traverse,		/* tp_traverse */
8057     (inquiry)PublicKey_clear,			/* tp_clear */
8058     0,						/* tp_richcompare */
8059     0,						/* tp_weaklistoffset */
8060     0,						/* tp_iter */
8061     0,						/* tp_iternext */
8062     PublicKey_methods,				/* tp_methods */
8063     PublicKey_members,				/* tp_members */
8064     PublicKey_getseters,			/* tp_getset */
8065     0,						/* tp_base */
8066     0,						/* tp_dict */
8067     0,						/* tp_descr_get */
8068     0,						/* tp_descr_set */
8069     0,						/* tp_dictoffset */
8070     (initproc)PublicKey_init,			/* tp_init */
8071     0,						/* tp_alloc */
8072     PublicKey_new,				/* tp_new */
8073 };
8074 
8075 PyObject *
PublicKey_new_from_SECKEYPublicKey(SECKEYPublicKey * pk)8076 PublicKey_new_from_SECKEYPublicKey(SECKEYPublicKey *pk)
8077 {
8078     PublicKey *self = NULL;
8079 
8080     TraceObjNewEnter(NULL);
8081 
8082     if ((self = (PublicKey *) PublicKeyType.tp_new(&PublicKeyType, NULL, NULL)) == NULL) {
8083         return NULL;
8084     }
8085 
8086     self->pk = pk;
8087 
8088     switch(pk->keyType) {       /* FIXME: handle the other cases */
8089     case rsaKey:
8090         if ((self->py_rsa_key = RSAPublicKey_new_from_SECKEYRSAPublicKey(&pk->u.rsa)) == NULL) {
8091             Py_CLEAR(self);
8092             return NULL;
8093         }
8094         break;
8095     case dsaKey:
8096         if ((self->py_dsa_key = DSAPublicKey_new_from_SECKEYDSAPublicKey(&pk->u.dsa)) == NULL) {
8097             Py_CLEAR(self);
8098             return NULL;
8099         }
8100         break;
8101     case fortezzaKey:
8102     case dhKey:
8103     case keaKey:
8104     case ecKey:
8105     case rsaPssKey:
8106     case rsaOaepKey:
8107     case nullKey:
8108         break;
8109     }
8110 
8111     TraceObjNewLeave(self);
8112     return (PyObject *) self;
8113 }
8114 
8115 /* ========================================================================== */
8116 /* ======================= SubjectPublicKeyInfo Class ======================= */
8117 /* ========================================================================== */
8118 
8119 /* ============================ Attribute Access ============================ */
8120 
8121 static PyObject *
SubjectPublicKeyInfo_get_algorithm(SubjectPublicKeyInfo * self,void * closure)8122 SubjectPublicKeyInfo_get_algorithm(SubjectPublicKeyInfo *self, void *closure)
8123 {
8124     TraceMethodEnter(self);
8125 
8126     Py_INCREF(self->py_algorithm);
8127     return self->py_algorithm;
8128 }
8129 
8130 static PyObject *
SubjectPublicKeyInfo_get_public_key(SubjectPublicKeyInfo * self,void * closure)8131 SubjectPublicKeyInfo_get_public_key(SubjectPublicKeyInfo *self, void *closure)
8132 {
8133     TraceMethodEnter(self);
8134 
8135     Py_INCREF(self->py_public_key);
8136     return self->py_public_key;
8137 }
8138 
8139 static
8140 PyGetSetDef SubjectPublicKeyInfo_getseters[] = {
8141     {"algorithm",  (getter)SubjectPublicKeyInfo_get_algorithm,  (setter)NULL, "algorithm", NULL},
8142     {"public_key", (getter)SubjectPublicKeyInfo_get_public_key, (setter)NULL, "PublicKey object", NULL},
8143     {NULL}  /* Sentinel */
8144 };
8145 
8146 static PyMemberDef SubjectPublicKeyInfo_members[] = {
8147     {NULL}  /* Sentinel */
8148 };
8149 
8150 /* ============================== Class Methods ============================= */
8151 
8152 static PyObject *
SubjectPublicKeyInfo_format_lines(SubjectPublicKeyInfo * self,PyObject * args,PyObject * kwds)8153 SubjectPublicKeyInfo_format_lines(SubjectPublicKeyInfo *self, PyObject *args, PyObject *kwds)
8154 {
8155     static char *kwlist[] = {"level", NULL};
8156     int level = 0;
8157     PyObject *lines = NULL;
8158     PyObject *py_public_key = NULL;
8159     PyObject *obj = NULL;
8160 
8161     TraceMethodEnter(self);
8162 
8163     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:format_lines", kwlist, &level))
8164         return NULL;
8165 
8166     if ((lines = PyList_New(0)) == NULL) {
8167         return NULL;
8168     }
8169 
8170     if ((obj = SubjectPublicKeyInfo_get_algorithm(self, NULL)) == NULL) {
8171         goto fail;
8172     }
8173     FMT_LABEL_AND_APPEND(lines, _("Public Key Algorithm"), level, fail);
8174     CALL_FORMAT_LINES_AND_APPEND(lines, obj, level+1, fail);
8175     Py_CLEAR(obj);
8176 
8177     if ((py_public_key = SubjectPublicKeyInfo_get_public_key(self, NULL)) == NULL) {
8178         goto fail;
8179     }
8180 
8181     CALL_FORMAT_LINES_AND_APPEND(lines, py_public_key, level, fail);
8182     Py_CLEAR(py_public_key);
8183 
8184     return lines;
8185  fail:
8186     Py_XDECREF(lines);
8187     Py_XDECREF(py_public_key);
8188     return NULL;
8189 }
8190 
8191 static PyObject *
SubjectPublicKeyInfo_format(SubjectPublicKeyInfo * self,PyObject * args,PyObject * kwds)8192 SubjectPublicKeyInfo_format(SubjectPublicKeyInfo *self, PyObject *args, PyObject *kwds)
8193 {
8194     TraceMethodEnter(self);
8195 
8196     return format_from_lines((format_lines_func)SubjectPublicKeyInfo_format_lines, (PyObject *)self, args, kwds);
8197 }
8198 
8199 static PyObject *
SubjectPublicKeyInfo_str(SubjectPublicKeyInfo * self)8200 SubjectPublicKeyInfo_str(SubjectPublicKeyInfo *self)
8201 {
8202     PyObject *py_formatted_result = NULL;
8203 
8204     py_formatted_result =  SubjectPublicKeyInfo_format(self, empty_tuple, NULL);
8205     return py_formatted_result;
8206 
8207 }
8208 
8209 static PyMethodDef SubjectPublicKeyInfo_methods[] = {
8210     {"format_lines", (PyCFunction)SubjectPublicKeyInfo_format_lines,   METH_VARARGS|METH_KEYWORDS, generic_format_lines_doc},
8211     {"format",       (PyCFunction)SubjectPublicKeyInfo_format,         METH_VARARGS|METH_KEYWORDS, generic_format_doc},
8212     {NULL, NULL}  /* Sentinel */
8213 };
8214 
8215 /* =========================== Class Construction =========================== */
8216 
8217 static PyObject *
SubjectPublicKeyInfo_new(PyTypeObject * type,PyObject * args,PyObject * kwds)8218 SubjectPublicKeyInfo_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
8219 {
8220     SubjectPublicKeyInfo *self;
8221 
8222     TraceObjNewEnter(type);
8223 
8224     if ((self = (SubjectPublicKeyInfo *)type->tp_alloc(type, 0)) == NULL) {
8225         return NULL;
8226     }
8227 
8228     self->py_algorithm = NULL;
8229     self->py_public_key = NULL;
8230 
8231     TraceObjNewLeave(self);
8232     return (PyObject *)self;
8233 }
8234 
8235 static int
SubjectPublicKeyInfo_traverse(SubjectPublicKeyInfo * self,visitproc visit,void * arg)8236 SubjectPublicKeyInfo_traverse(SubjectPublicKeyInfo *self, visitproc visit, void *arg)
8237 {
8238     TraceMethodEnter(self);
8239 
8240     Py_VISIT(self->py_algorithm);
8241     Py_VISIT(self->py_public_key);
8242     return 0;
8243 }
8244 
8245 static int
SubjectPublicKeyInfo_clear(SubjectPublicKeyInfo * self)8246 SubjectPublicKeyInfo_clear(SubjectPublicKeyInfo* self)
8247 {
8248     TraceMethodEnter(self);
8249 
8250     DumpRefCount(self->py_public_key);
8251     Py_CLEAR(self->py_algorithm);
8252     Py_CLEAR(self->py_public_key);
8253     return 0;
8254 }
8255 
8256 static void
SubjectPublicKeyInfo_dealloc(SubjectPublicKeyInfo * self)8257 SubjectPublicKeyInfo_dealloc(SubjectPublicKeyInfo* self)
8258 {
8259     TraceMethodEnter(self);
8260 
8261     SubjectPublicKeyInfo_clear(self);
8262     Py_TYPE(self)->tp_free((PyObject*)self);
8263 }
8264 
8265 PyDoc_STRVAR(SubjectPublicKeyInfo_doc,
8266 "An object representing a Subject Public Key");
8267 
8268 static int
SubjectPublicKeyInfo_init(SubjectPublicKeyInfo * self,PyObject * args,PyObject * kwds)8269 SubjectPublicKeyInfo_init(SubjectPublicKeyInfo *self, PyObject *args, PyObject *kwds)
8270 {
8271     TraceMethodEnter(self);
8272 
8273     return 0;
8274 }
8275 
8276 static PyTypeObject SubjectPublicKeyInfoType = {
8277     PyVarObject_HEAD_INIT(NULL, 0)
8278     "nss.nss.SubjectPublicKeyInfo",		/* tp_name */
8279     sizeof(SubjectPublicKeyInfo),		/* tp_basicsize */
8280     0,						/* tp_itemsize */
8281     (destructor)SubjectPublicKeyInfo_dealloc,	/* tp_dealloc */
8282     0,						/* tp_print */
8283     0,						/* tp_getattr */
8284     0,						/* tp_setattr */
8285     0,						/* tp_compare */
8286     0,						/* tp_repr */
8287     0,						/* tp_as_number */
8288     0,						/* tp_as_sequence */
8289     0,						/* tp_as_mapping */
8290     0,						/* tp_hash */
8291     0,						/* tp_call */
8292     (reprfunc)SubjectPublicKeyInfo_str,		/* tp_str */
8293     0,						/* tp_getattro */
8294     0,						/* tp_setattro */
8295     0,						/* tp_as_buffer */
8296     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,	/* tp_flags */
8297     SubjectPublicKeyInfo_doc,			/* tp_doc */
8298     (traverseproc)SubjectPublicKeyInfo_traverse, /* tp_traverse */
8299     (inquiry)SubjectPublicKeyInfo_clear,	/* tp_clear */
8300     0,						/* tp_richcompare */
8301     0,						/* tp_weaklistoffset */
8302     0,						/* tp_iter */
8303     0,						/* tp_iternext */
8304     SubjectPublicKeyInfo_methods,		/* tp_methods */
8305     SubjectPublicKeyInfo_members,		/* tp_members */
8306     SubjectPublicKeyInfo_getseters,		/* tp_getset */
8307     0,						/* tp_base */
8308     0,						/* tp_dict */
8309     0,						/* tp_descr_get */
8310     0,						/* tp_descr_set */
8311     0,						/* tp_dictoffset */
8312     (initproc)SubjectPublicKeyInfo_init,	/* tp_init */
8313     0,						/* tp_alloc */
8314     SubjectPublicKeyInfo_new,			/* tp_new */
8315 };
8316 
8317 PyObject *
SubjectPublicKeyInfo_new_from_CERTSubjectPublicKeyInfo(CERTSubjectPublicKeyInfo * spki)8318 SubjectPublicKeyInfo_new_from_CERTSubjectPublicKeyInfo(CERTSubjectPublicKeyInfo *spki)
8319 {
8320     SubjectPublicKeyInfo *self = NULL;
8321     SECKEYPublicKey *pk = NULL;
8322 
8323     TraceObjNewEnter(NULL);
8324 
8325     if ((self = (SubjectPublicKeyInfo *) SubjectPublicKeyInfoType.tp_new(&SubjectPublicKeyInfoType, NULL, NULL)) == NULL) {
8326         return NULL;
8327     }
8328 
8329     if ((self->py_algorithm = AlgorithmID_new_from_SECAlgorithmID(&spki->algorithm)) == NULL) {
8330         Py_CLEAR(self);
8331         return NULL;
8332     }
8333 
8334     if ((pk = SECKEY_ExtractPublicKey(spki)) == NULL) {
8335         set_nspr_error(NULL);
8336         Py_CLEAR(self);
8337         return NULL;
8338     }
8339 
8340     if ((self->py_public_key = PublicKey_new_from_SECKEYPublicKey(pk)) == NULL) {
8341 	SECKEY_DestroyPublicKey(pk);
8342         Py_CLEAR(self);
8343         return NULL;
8344     }
8345     DumpRefCount(self->py_public_key);
8346 
8347     TraceObjNewLeave(self);
8348     return (PyObject *) self;
8349 }
8350 
8351 /* ============================== Utilities ============================= */
8352 
8353 static CERTDistNames *
cert_distnames_as_CERTDistNames(PyObject * py_distnames)8354 cert_distnames_as_CERTDistNames(PyObject *py_distnames)
8355 {
8356     PRArenaPool *arena = NULL;
8357     CERTDistNames *names = NULL;
8358     int i;
8359     SecItem *py_sec_item;
8360 
8361     if (!(PyList_Check(py_distnames) || PyTuple_Check(py_distnames))) {
8362         PyErr_SetString(PyExc_TypeError, "cert distnames must be a list or tuple");
8363         return NULL;
8364     }
8365 
8366     /* allocate an arena to use */
8367     if ((arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE)) == NULL ) {
8368         set_nspr_error(NULL);
8369         return NULL;
8370     }
8371 
8372     /* allocate the header structure */
8373     if ((names = (CERTDistNames *)PORT_ArenaAlloc(arena, sizeof(CERTDistNames))) == NULL) {
8374         PORT_FreeArena(arena, PR_FALSE);
8375         PyErr_NoMemory();
8376         return NULL;
8377     }
8378 
8379     /* initialize the header struct */
8380     names->arena = arena;
8381     names->head = NULL;
8382     names->nnames = PySequence_Size(py_distnames);
8383     names->names = NULL;
8384 
8385     /* construct the array from the list */
8386     if (names->nnames) {
8387 	names->names = (SECItem *)PORT_ArenaAlloc(arena, names->nnames * sizeof(SECItem));
8388 
8389 	if (names->names == NULL) {
8390             PORT_FreeArena(arena, PR_FALSE);
8391             PyErr_NoMemory();
8392             return NULL;
8393 	}
8394 
8395 	for (i = 0; i < names->nnames; i++) {
8396             py_sec_item = (SecItem *)PySequence_GetItem(py_distnames, i); /* new reference */
8397             if ((!PySecItem_Check(py_sec_item)) || (py_sec_item->kind != SECITEM_dist_name)) {
8398                 PyErr_Format(PyExc_TypeError, "item must be a %s containing a DistName",
8399                              SecItemType.tp_name);
8400                 Py_DECREF(py_sec_item);
8401                 PORT_FreeArena(arena, PR_FALSE);
8402                 return NULL;
8403             }
8404             if (SECITEM_CopyItem(arena, &names->names[i], &py_sec_item->item) != SECSuccess) {
8405                 Py_DECREF(py_sec_item);
8406                 PORT_FreeArena(arena, PR_FALSE);
8407                 return NULL;
8408             }
8409             Py_DECREF(py_sec_item);
8410 	}
8411     }
8412     return names;
8413 }
8414 
8415 /* ========================================================================== */
8416 /* =============================== CertDB Class ============================= */
8417 /* ========================================================================== */
8418 
8419 /* ============================ Attribute Access ============================ */
8420 
8421 static
8422 PyGetSetDef CertDB_getseters[] = {
8423     {NULL}  /* Sentinel */
8424 };
8425 
8426 static PyMemberDef CertDB_members[] = {
8427     {NULL}  /* Sentinel */
8428 };
8429 
8430 /* ============================== Class Methods ============================= */
8431 
8432 PyDoc_STRVAR(CertDB_find_crl_by_name_doc,
8433 "find_crl_by_name(name, type=SEC_CRL_TYPE) -> SignedCRL object\n\
8434 \n\
8435 :Parameters:\n\
8436     name : string\n\
8437         name to lookup\n\
8438     type : int\n\
8439         revocation list type\n\
8440         \n\
8441         may be one of:\n\
8442           - SEC_CRL_TYPE\n\
8443           - SEC_KRL_TYPE\n\
8444 \n\
8445 Returns a SignedCRL object found in the database given a name and revocation list type.\n\
8446 "
8447 );
8448 static PyObject *
CertDB_find_crl_by_name(CertDB * self,PyObject * args,PyObject * kwds)8449 CertDB_find_crl_by_name(CertDB *self, PyObject *args, PyObject *kwds)
8450 {
8451     static char *kwlist[] = {"name", "type", NULL};
8452     char *name;
8453     int type = SEC_CRL_TYPE;
8454     CERTName *cert_name;
8455     SECItem *der_name;
8456     CERTSignedCrl *signed_crl;
8457 
8458     TraceMethodEnter(self);
8459 
8460     if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|i:find_crl_by_name", kwlist,
8461                                      &name, &type))
8462         return NULL;
8463 
8464     if ((cert_name = CERT_AsciiToName(name)) == NULL) {
8465         return set_nspr_error(NULL);
8466     }
8467 
8468     if ((der_name = SEC_ASN1EncodeItem (NULL, NULL, (void *)cert_name,
8469                                         SEC_ASN1_GET(CERT_NameTemplate))) == NULL) {
8470         CERT_DestroyName(cert_name);
8471         return set_nspr_error(NULL);
8472     }
8473     CERT_DestroyName(cert_name);
8474 
8475     if ((signed_crl = SEC_FindCrlByName(self->handle, der_name, type)) == NULL) {
8476         SECITEM_FreeItem(der_name, PR_TRUE);
8477         return set_nspr_error(NULL);
8478     }
8479     SECITEM_FreeItem(der_name, PR_TRUE);
8480 
8481     return SignedCRL_new_from_CERTSignedCRL(signed_crl);
8482 }
8483 
8484 PyDoc_STRVAR(CertDB_find_crl_by_cert_doc,
8485 "find_crl_by_cert(cert, type=SEC_CRL_TYPE) -> SignedCRL object\n\
8486 \n\
8487 :Parameters:\n\
8488     cert : Certificate object\n\
8489         certificate used to lookup the CRL.\n\
8490     type : int\n\
8491         revocation list type\n\
8492         \n\
8493         may be one of:\n\
8494           - SEC_CRL_TYPE\n\
8495           - SEC_KRL_TYPE\n\
8496 \n\
8497 Returns a SignedCRL object found in the database given a certificate and revocation list type.\n\
8498 "
8499 );
8500 static PyObject *
CertDB_find_crl_by_cert(CertDB * self,PyObject * args,PyObject * kwds)8501 CertDB_find_crl_by_cert(CertDB *self, PyObject *args, PyObject *kwds)
8502 {
8503     static char *kwlist[] = {"cert", "type", NULL};
8504     int type = SEC_CRL_TYPE;
8505     Certificate *py_cert = NULL;
8506     SECItem *der_cert;
8507     CERTSignedCrl *signed_crl;
8508 
8509     TraceMethodEnter(self);
8510 
8511     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|i:find_crl_by_cert", kwlist,
8512                                      &CertificateType, &py_cert, &type))
8513         return NULL;
8514 
8515     der_cert = &py_cert->cert->derCert;
8516     if ((signed_crl = SEC_FindCrlByDERCert(self->handle, der_cert, type)) == NULL) {
8517         return set_nspr_error(NULL);
8518     }
8519 
8520     return SignedCRL_new_from_CERTSignedCRL(signed_crl);
8521 }
8522 
8523 
8524 static PyMethodDef CertDB_methods[] = {
8525     {"find_crl_by_name", (PyCFunction)CertDB_find_crl_by_name, METH_VARARGS|METH_KEYWORDS, CertDB_find_crl_by_name_doc},
8526     {"find_crl_by_cert", (PyCFunction)CertDB_find_crl_by_cert, METH_VARARGS|METH_KEYWORDS, CertDB_find_crl_by_cert_doc},
8527     {NULL, NULL}  /* Sentinel */
8528 };
8529 
8530 /* =========================== Class Construction =========================== */
8531 
8532 static PyObject *
CertDB_new(PyTypeObject * type,PyObject * args,PyObject * kwds)8533 CertDB_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
8534 {
8535     CertDB *self;
8536 
8537     TraceObjNewEnter(type);
8538 
8539     if ((self = (CertDB *)type->tp_alloc(type, 0)) == NULL) {
8540         return NULL;
8541     }
8542     self->handle = NULL;
8543 
8544     TraceObjNewLeave(self);
8545     return (PyObject *)self;
8546 }
8547 
8548 static void
CertDB_dealloc(CertDB * self)8549 CertDB_dealloc(CertDB* self)
8550 {
8551     TraceMethodEnter(self);
8552 
8553     Py_TYPE(self)->tp_free((PyObject*)self);
8554 }
8555 
8556 PyDoc_STRVAR(CertDB_doc,
8557 "An object representing a Certificate Database");
8558 
8559 static int
CertDB_init(CertDB * self,PyObject * args,PyObject * kwds)8560 CertDB_init(CertDB *self, PyObject *args, PyObject *kwds)
8561 {
8562     TraceMethodEnter(self);
8563     return 0;
8564 }
8565 
8566 static PyTypeObject CertDBType = {
8567     PyVarObject_HEAD_INIT(NULL, 0)
8568     "nss.nss.CertDB",				/* tp_name */
8569     sizeof(CertDB),				/* tp_basicsize */
8570     0,						/* tp_itemsize */
8571     (destructor)CertDB_dealloc,			/* tp_dealloc */
8572     0,						/* tp_print */
8573     0,						/* tp_getattr */
8574     0,						/* tp_setattr */
8575     0,						/* tp_compare */
8576     0,						/* tp_repr */
8577     0,						/* tp_as_number */
8578     0,						/* tp_as_sequence */
8579     0,						/* tp_as_mapping */
8580     0,						/* tp_hash */
8581     0,						/* tp_call */
8582     0,						/* tp_str */
8583     0,						/* tp_getattro */
8584     0,						/* tp_setattro */
8585     0,						/* tp_as_buffer */
8586     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,	/* tp_flags */
8587     CertDB_doc,					/* tp_doc */
8588     0,						/* tp_traverse */
8589     0,						/* tp_clear */
8590     0,						/* tp_richcompare */
8591     0,						/* tp_weaklistoffset */
8592     0,						/* tp_iter */
8593     0,						/* tp_iternext */
8594     CertDB_methods,				/* tp_methods */
8595     CertDB_members,				/* tp_members */
8596     CertDB_getseters,				/* tp_getset */
8597     0,						/* tp_base */
8598     0,						/* tp_dict */
8599     0,						/* tp_descr_get */
8600     0,						/* tp_descr_set */
8601     0,						/* tp_dictoffset */
8602     (initproc)CertDB_init,			/* tp_init */
8603     0,						/* tp_alloc */
8604     CertDB_new,					/* tp_new */
8605 };
8606 
8607 PyObject *
CertDB_new_from_CERTCertDBHandle(CERTCertDBHandle * certdb_handle)8608 CertDB_new_from_CERTCertDBHandle(CERTCertDBHandle *certdb_handle)
8609 {
8610     CertDB *self = NULL;
8611 
8612     TraceObjNewEnter(NULL);
8613     if ((self = (CertDB *) CertDBType.tp_new(&CertDBType, NULL, NULL)) == NULL) {
8614         return NULL;
8615     }
8616 
8617     self->handle = certdb_handle;
8618 
8619     TraceObjNewLeave(self);
8620     return (PyObject *) self;
8621 }
8622 
8623 static PyObject *
cert_distnames_new_from_CERTDistNames(CERTDistNames * names)8624 cert_distnames_new_from_CERTDistNames(CERTDistNames *names)
8625 {
8626     PyObject *py_distnames = NULL;
8627     PyObject *py_sec_item = NULL;
8628     int i, len;
8629 
8630     len = names->nnames;
8631     if ((py_distnames = PyTuple_New(len)) == NULL) {
8632         return NULL;
8633     }
8634 
8635     for (i = 0; i< names->nnames; i++) {
8636         if ((py_sec_item = SecItem_new_from_SECItem(&names->names[i], SECITEM_dist_name)) == NULL) {
8637             Py_DECREF(py_distnames);
8638             return NULL;
8639         }
8640         PyTuple_SetItem(py_distnames, i, py_sec_item);
8641     }
8642 
8643     return py_distnames;
8644 }
8645 
8646 /* ========================================================================== */
8647 /* ======================== CertificateExtension Class ====================== */
8648 /* ========================================================================== */
8649 
8650 /* ============================ Attribute Access ============================ */
8651 
8652 static PyObject *
CertificateExtension_get_name(CertificateExtension * self,void * closure)8653 CertificateExtension_get_name(CertificateExtension *self, void *closure)
8654 {
8655     TraceMethodEnter(self);
8656 
8657     return oid_secitem_to_pystr_desc(&self->py_oid->item);
8658 }
8659 
8660 static PyObject *
CertificateExtension_get_critical(CertificateExtension * self,void * closure)8661 CertificateExtension_get_critical(CertificateExtension *self, void *closure)
8662 {
8663     TraceMethodEnter(self);
8664 
8665     return PyBool_FromLong(self->critical);
8666 }
8667 
8668 static PyObject *
CertificateExtension_get_oid(CertificateExtension * self,void * closure)8669 CertificateExtension_get_oid(CertificateExtension *self, void *closure)
8670 {
8671     TraceMethodEnter(self);
8672 
8673     Py_INCREF(self->py_oid);
8674     return (PyObject *)self->py_oid;
8675 }
8676 
8677 static PyObject *
CertificateExtension_get_oid_tag(CertificateExtension * self,void * closure)8678 CertificateExtension_get_oid_tag(CertificateExtension *self, void *closure)
8679 {
8680     TraceMethodEnter(self);
8681 
8682     return oid_secitem_to_pyint_tag(&self->py_oid->item);
8683 }
8684 
8685 static PyObject *
CertificateExtension_get_value(CertificateExtension * self,void * closure)8686 CertificateExtension_get_value(CertificateExtension *self, void *closure)
8687 {
8688     TraceMethodEnter(self);
8689 
8690     Py_INCREF(self->py_value);
8691     return (PyObject *)self->py_value;
8692 }
8693 
8694 static
8695 PyGetSetDef CertificateExtension_getseters[] = {
8696     {"name",     (getter)CertificateExtension_get_name,     (setter)NULL, "name of extension", NULL},
8697     {"critical", (getter)CertificateExtension_get_critical, (setter)NULL, "extension is critical flag (boolean)", NULL},
8698     {"oid",      (getter)CertificateExtension_get_oid,      (setter)NULL, "oid of extension as SecItem", NULL},
8699     {"oid_tag",  (getter)CertificateExtension_get_oid_tag,  (setter)NULL, "oid of extension as a enumerated constant (e.g. tag)", NULL},
8700     {"value",    (getter)CertificateExtension_get_value,    (setter)NULL, "extension data as SecItem", NULL},
8701     {NULL}  /* Sentinel */
8702 };
8703 
8704 static PyMemberDef CertificateExtension_members[] = {
8705     {NULL}  /* Sentinel */
8706 };
8707 
8708 /* ============================== Class Methods ============================= */
8709 
8710 static PyObject *
CertificateExtension_format_lines(CertificateExtension * self,PyObject * args,PyObject * kwds)8711 CertificateExtension_format_lines(CertificateExtension *self, PyObject *args, PyObject *kwds)
8712 {
8713     static char *kwlist[] = {"level", NULL};
8714     int level = 0;
8715     PyObject *lines = NULL;
8716     PyObject *obj = NULL;
8717     PyObject *obj1 = NULL;
8718     SECOidTag oid_tag;
8719     PyObject *obj_lines = NULL;
8720     PyObject *tmp_args = NULL;
8721 
8722     TraceMethodEnter(self);
8723 
8724     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:format_lines", kwlist, &level))
8725         return NULL;
8726 
8727     if ((lines = PyList_New(0)) == NULL) {
8728         goto fail;
8729     }
8730 
8731     if ((obj = CertificateExtension_get_name(self, NULL)) == NULL) {
8732         goto fail;
8733     }
8734     FMT_OBJ_AND_APPEND(lines, _("Name"), obj, level, fail);
8735     Py_CLEAR(obj);
8736 
8737     if ((obj = CertificateExtension_get_critical(self, NULL)) == NULL) {
8738         goto fail;
8739     }
8740     FMT_OBJ_AND_APPEND(lines, _("Critical"), obj, level, fail);
8741     Py_CLEAR(obj);
8742 
8743     oid_tag = SECOID_FindOIDTag(&self->py_oid->item);
8744 
8745     switch(oid_tag) {
8746     case SEC_OID_PKCS12_KEY_USAGE:
8747         FMT_LABEL_AND_APPEND(lines, _("Usages"), level, fail);
8748         if ((tmp_args = Py_BuildValue("(O)", self->py_value)) == NULL) {
8749             goto fail;
8750         }
8751         if ((obj = cert_x509_key_usage(NULL, tmp_args, NULL)) == NULL) {
8752             goto fail;
8753         }
8754         Py_CLEAR(tmp_args);
8755         if ((obj_lines = make_line_fmt_tuples(level+1, obj)) == NULL) {
8756             goto fail;
8757         }
8758         APPEND_LINE_TUPLES_AND_CLEAR(lines, obj_lines, fail);
8759         break;
8760 
8761     case SEC_OID_NS_CERT_EXT_CERT_TYPE:
8762         FMT_LABEL_AND_APPEND(lines, _("Types"), level, fail);
8763         if ((tmp_args = Py_BuildValue("(O)", self->py_value)) == NULL) {
8764             goto fail;
8765         }
8766         if ((obj = cert_x509_cert_type(NULL, tmp_args, NULL)) == NULL) {
8767             goto fail;
8768         }
8769         Py_CLEAR(tmp_args);
8770         if ((obj_lines = make_line_fmt_tuples(level+1, obj)) == NULL) {
8771             goto fail;
8772         }
8773         APPEND_LINE_TUPLES_AND_CLEAR(lines, obj_lines, fail);
8774         break;
8775 
8776     case SEC_OID_X509_SUBJECT_KEY_ID:
8777         FMT_LABEL_AND_APPEND(lines, _("Data"), level, fail);
8778         if ((obj_lines = SECItem_der_to_hex(&self->py_value->item,
8779                                             OCTETS_PER_LINE_DEFAULT, HEX_SEPARATOR_DEFAULT)) == NULL) {
8780             goto fail;
8781         }
8782         APPEND_LINES_AND_CLEAR(lines, obj_lines, level+1, fail);
8783         break;
8784 
8785     case SEC_OID_X509_CRL_DIST_POINTS:
8786         if ((obj = CRLDistributionPts_new_from_SECItem(&self->py_value->item)) == NULL) {
8787             goto fail;
8788         }
8789         CALL_FORMAT_LINES_AND_APPEND(lines, obj, level, fail);
8790         Py_CLEAR(obj);
8791         break;
8792 
8793     case SEC_OID_X509_AUTH_INFO_ACCESS:
8794         if ((obj = AuthorityInfoAccesses_new_from_SECItem(&self->py_value->item)) == NULL) {
8795             goto fail;
8796         }
8797         CALL_FORMAT_LINES_AND_APPEND(lines, obj, level, fail);
8798         Py_CLEAR(obj);
8799         break;
8800 
8801     case SEC_OID_X509_AUTH_KEY_ID:
8802         if ((obj = AuthKeyID_new_from_SECItem(&self->py_value->item)) == NULL) {
8803             goto fail;
8804         }
8805         CALL_FORMAT_LINES_AND_APPEND(lines, obj, level, fail);
8806         Py_CLEAR(obj);
8807 
8808         break;
8809 
8810     case SEC_OID_X509_EXT_KEY_USAGE:
8811         FMT_LABEL_AND_APPEND(lines, _("Usages"), level, fail);
8812         if ((tmp_args = Py_BuildValue("(O)", self->py_value)) == NULL) {
8813             goto fail;
8814         }
8815         if ((obj = cert_x509_ext_key_usage(NULL, tmp_args, NULL)) == NULL) {
8816             goto fail;
8817         }
8818         Py_CLEAR(tmp_args);
8819         if ((obj_lines = make_line_fmt_tuples(level+1, obj)) == NULL) {
8820             goto fail;
8821         }
8822         APPEND_LINE_TUPLES_AND_CLEAR(lines, obj_lines, fail);
8823         break;
8824 
8825     case SEC_OID_X509_BASIC_CONSTRAINTS:
8826         if ((obj = BasicConstraints_new_from_SECItem(&self->py_value->item)) == NULL) {
8827             goto fail;
8828         }
8829         CALL_FORMAT_LINES_AND_APPEND(lines, obj, level, fail);
8830         Py_CLEAR(obj);
8831 
8832         break;
8833 
8834     case SEC_OID_X509_SUBJECT_ALT_NAME:
8835     case SEC_OID_X509_ISSUER_ALT_NAME:
8836         FMT_LABEL_AND_APPEND(lines, _("Names"), level, fail);
8837         if ((tmp_args = Py_BuildValue("(O)", self->py_value)) == NULL) {
8838             goto fail;
8839         }
8840         if ((obj = cert_x509_alt_name(NULL, tmp_args, NULL)) == NULL) {
8841             goto fail;
8842         }
8843         Py_CLEAR(tmp_args);
8844         if ((obj_lines = make_line_fmt_tuples(level+1, obj)) == NULL) {
8845             goto fail;
8846         }
8847         APPEND_LINE_TUPLES_AND_CLEAR(lines, obj_lines, fail);
8848         break;
8849 
8850     default:
8851         break;
8852     }
8853 
8854     return lines;
8855 
8856  fail:
8857     Py_XDECREF(lines);
8858     Py_XDECREF(obj);
8859     Py_XDECREF(obj1);
8860     Py_XDECREF(obj_lines);
8861     Py_XDECREF(tmp_args);
8862     return NULL;
8863 }
8864 
8865 static PyObject *
CertificateExtension_format(CertificateExtension * self,PyObject * args,PyObject * kwds)8866 CertificateExtension_format(CertificateExtension *self, PyObject *args, PyObject *kwds)
8867 {
8868     TraceMethodEnter(self);
8869 
8870     return format_from_lines((format_lines_func)CertificateExtension_format_lines, (PyObject *)self, args, kwds);
8871 }
8872 
8873 static PyObject *
CertificateExtension_repr(CertificateExtension * self)8874 CertificateExtension_repr(CertificateExtension *self)
8875 {
8876     TraceMethodEnter(self);
8877 
8878     return oid_secitem_to_pystr_desc(&self->py_oid->item);
8879 }
8880 
8881 static PyObject *
CertificateExtension_str(CertificateExtension * self)8882 CertificateExtension_str(CertificateExtension *self)
8883 {
8884     PyObject *py_formatted_result = NULL;
8885 
8886     TraceMethodEnter(self);
8887 
8888     py_formatted_result =  CertificateExtension_format(self, empty_tuple, NULL);
8889     return py_formatted_result;
8890 
8891 }
8892 
8893 static PyMethodDef CertificateExtension_methods[] = {
8894     {"format_lines", (PyCFunction)CertificateExtension_format_lines,   METH_VARARGS|METH_KEYWORDS, generic_format_lines_doc},
8895     {"format",       (PyCFunction)CertificateExtension_format,         METH_VARARGS|METH_KEYWORDS, generic_format_doc},
8896     {NULL, NULL}  /* Sentinel */
8897 };
8898 
8899 /* =========================== Class Construction =========================== */
8900 
8901 static PyObject *
CertificateExtension_new(PyTypeObject * type,PyObject * args,PyObject * kwds)8902 CertificateExtension_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
8903 {
8904     CertificateExtension *self;
8905 
8906     TraceObjNewEnter(type);
8907 
8908     if ((self = (CertificateExtension *)type->tp_alloc(type, 0)) == NULL) {
8909         return NULL;
8910     }
8911 
8912     self->py_oid = NULL;
8913     self->py_value = NULL;
8914     self->critical = 0;
8915 
8916     TraceObjNewLeave(self);
8917     return (PyObject *)self;
8918 }
8919 
8920 static int
CertificateExtension_traverse(CertificateExtension * self,visitproc visit,void * arg)8921 CertificateExtension_traverse(CertificateExtension *self, visitproc visit, void *arg)
8922 {
8923     TraceMethodEnter(self);
8924 
8925     Py_VISIT(self->py_oid);
8926     Py_VISIT(self->py_value);
8927     return 0;
8928 }
8929 
8930 static int
CertificateExtension_clear(CertificateExtension * self)8931 CertificateExtension_clear(CertificateExtension* self)
8932 {
8933     TraceMethodEnter(self);
8934 
8935     Py_CLEAR(self->py_oid);
8936     Py_CLEAR(self->py_value);
8937     return 0;
8938 }
8939 
8940 static void
CertificateExtension_dealloc(CertificateExtension * self)8941 CertificateExtension_dealloc(CertificateExtension* self)
8942 {
8943     TraceMethodEnter(self);
8944 
8945     CertificateExtension_clear(self);
8946     Py_TYPE(self)->tp_free((PyObject*)self);
8947 }
8948 
8949 PyDoc_STRVAR(CertificateExtension_doc,
8950 "An object representing a certificate extension");
8951 
8952 static int
CertificateExtension_init(CertificateExtension * self,PyObject * args,PyObject * kwds)8953 CertificateExtension_init(CertificateExtension *self, PyObject *args, PyObject *kwds)
8954 {
8955     TraceMethodEnter(self);
8956     return 0;
8957 }
8958 
8959 static PyTypeObject CertificateExtensionType = {
8960     PyVarObject_HEAD_INIT(NULL, 0)
8961     "nss.nss.CertificateExtension",		/* tp_name */
8962     sizeof(CertificateExtension),		/* tp_basicsize */
8963     0,						/* tp_itemsize */
8964     (destructor)CertificateExtension_dealloc,	/* tp_dealloc */
8965     0,						/* tp_print */
8966     0,						/* tp_getattr */
8967     0,						/* tp_setattr */
8968     0,						/* tp_compare */
8969     (reprfunc)CertificateExtension_repr,	/* tp_repr */
8970     0,						/* tp_as_number */
8971     0,						/* tp_as_sequence */
8972     0,						/* tp_as_mapping */
8973     0,						/* tp_hash */
8974     0,						/* tp_call */
8975     (reprfunc)CertificateExtension_str,		/* tp_str */
8976     0,						/* tp_getattro */
8977     0,						/* tp_setattro */
8978     0,						/* tp_as_buffer */
8979     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,	/* tp_flags */
8980     CertificateExtension_doc,			/* tp_doc */
8981     (traverseproc)CertificateExtension_traverse,/* tp_traverse */
8982     (inquiry)CertificateExtension_clear,	/* tp_clear */
8983     0,						/* tp_richcompare */
8984     0,						/* tp_weaklistoffset */
8985     0,						/* tp_iter */
8986     0,						/* tp_iternext */
8987     CertificateExtension_methods,		/* tp_methods */
8988     CertificateExtension_members,		/* tp_members */
8989     CertificateExtension_getseters,		/* tp_getset */
8990     0,						/* tp_base */
8991     0,						/* tp_dict */
8992     0,						/* tp_descr_get */
8993     0,						/* tp_descr_set */
8994     0,						/* tp_dictoffset */
8995     (initproc)CertificateExtension_init,	/* tp_init */
8996     0,						/* tp_alloc */
8997     CertificateExtension_new,			/* tp_new */
8998 };
8999 
9000 PyObject *
CertificateExtension_new_from_CERTCertExtension(CERTCertExtension * extension)9001 CertificateExtension_new_from_CERTCertExtension(CERTCertExtension *extension)
9002 {
9003     CertificateExtension *self = NULL;
9004 
9005     TraceObjNewEnter(NULL);
9006     if ((self = (CertificateExtension *) CertificateExtensionType.tp_new(&CertificateExtensionType, NULL, NULL)) == NULL) {
9007         return NULL;
9008     }
9009 
9010     if ((self->py_oid = (SecItem *)
9011          SecItem_new_from_SECItem(&extension->id, SECITEM_cert_extension_oid)) == NULL) {
9012         Py_CLEAR(self);
9013         return NULL;
9014     }
9015 
9016     if ((self->py_value = (SecItem *)
9017          SecItem_new_from_SECItem(&extension->value, SECITEM_cert_extension_value)) == NULL) {
9018         Py_CLEAR(self);
9019         return NULL;
9020     }
9021 
9022     if (extension->critical.data && extension->critical.len) {
9023 	self->critical = extension->critical.data[0];
9024     }
9025 
9026     TraceObjNewLeave(self);
9027     return (PyObject *) self;
9028 }
9029 
9030 /* ========================================================================== */
9031 /* ============================ Certificate Class =========================== */
9032 /* ========================================================================== */
9033 
9034 /* ============================ Attribute Access ============================ */
9035 
9036 static PyObject *
Certificate_get_valid_not_before(Certificate * self,void * closure)9037 Certificate_get_valid_not_before(Certificate *self, void *closure)
9038 {
9039     PRTime pr_time = 0;
9040     double d_time;
9041 
9042     TraceMethodEnter(self);
9043 
9044     pr_time = time_choice_secitem_to_prtime(&self->cert->validity.notBefore);
9045     LL_L2D(d_time, pr_time);
9046 
9047     return PyFloat_FromDouble(d_time);
9048 }
9049 
9050 static PyObject *
Certificate_get_valid_not_before_str(Certificate * self,void * closure)9051 Certificate_get_valid_not_before_str(Certificate *self, void *closure)
9052 {
9053     TraceMethodEnter(self);
9054 
9055     return time_choice_secitem_to_pystr(&self->cert->validity.notBefore);
9056 }
9057 
9058 static PyObject *
Certificate_get_valid_not_after(Certificate * self,void * closure)9059 Certificate_get_valid_not_after(Certificate *self, void *closure)
9060 {
9061     PRTime pr_time = 0;
9062     double d_time;
9063 
9064     TraceMethodEnter(self);
9065 
9066     pr_time = time_choice_secitem_to_prtime(&self->cert->validity.notAfter);
9067     LL_L2D(d_time, pr_time);
9068 
9069     return PyFloat_FromDouble(d_time);
9070 }
9071 
9072 static PyObject *
Certificate_get_valid_not_after_str(Certificate * self,void * closure)9073 Certificate_get_valid_not_after_str(Certificate *self, void *closure)
9074 {
9075     TraceMethodEnter(self);
9076 
9077     return time_choice_secitem_to_pystr(&self->cert->validity.notAfter);
9078 }
9079 
9080 static PyObject *
Certificate_get_subject(Certificate * self,void * closure)9081 Certificate_get_subject(Certificate *self, void *closure)
9082 {
9083     TraceMethodEnter(self);
9084 
9085     return DN_new_from_CERTName(&self->cert->subject);
9086 }
9087 
9088 static PyObject *
Certificate_get_subject_common_name(Certificate * self,void * closure)9089 Certificate_get_subject_common_name(Certificate *self, void *closure)
9090 {
9091     char *cn;
9092     PyObject *py_cn = NULL;
9093 
9094     TraceMethodEnter(self);
9095 
9096     if ((cn = CERT_GetCommonName(&self->cert->subject)) == NULL) {
9097         Py_RETURN_NONE;
9098     }
9099 
9100     py_cn = PyUnicode_FromString(cn);
9101     PORT_Free(cn);
9102 
9103     return py_cn;
9104 }
9105 
9106 static PyObject *
Certificate_get_issuer(Certificate * self,void * closure)9107 Certificate_get_issuer(Certificate *self, void *closure)
9108 {
9109     TraceMethodEnter(self);
9110 
9111     return DN_new_from_CERTName(&self->cert->issuer);
9112 }
9113 
9114 static PyObject *
Certificate_get_version(Certificate * self,void * closure)9115 Certificate_get_version(Certificate *self, void *closure)
9116 {
9117     TraceMethodEnter(self);
9118 
9119     return integer_secitem_to_pylong(&self->cert->version);
9120 }
9121 
9122 static PyObject *
Certificate_get_serial_number(Certificate * self,void * closure)9123 Certificate_get_serial_number(Certificate *self, void *closure)
9124 {
9125     TraceMethodEnter(self);
9126 
9127     return integer_secitem_to_pylong(&self->cert->serialNumber);
9128 }
9129 
9130 // FIXME: should this come from SignedData?
9131 static PyObject *
Certificate_get_signature_algorithm(Certificate * self,void * closure)9132 Certificate_get_signature_algorithm(Certificate *self, void *closure)
9133 {
9134     TraceMethodEnter(self);
9135 
9136     return AlgorithmID_new_from_SECAlgorithmID(&self->cert->signature);
9137 }
9138 
9139 static PyObject *
Certificate_get_signed_data(Certificate * self,void * closure)9140 Certificate_get_signed_data(Certificate *self, void *closure)
9141 {
9142     TraceMethodEnter(self);
9143 
9144     return SignedData_new_from_SECItem(&self->cert->derCert);
9145 }
9146 
9147 static PyObject *
Certificate_get_der_data(Certificate * self,void * closure)9148 Certificate_get_der_data(Certificate *self, void *closure)
9149 {
9150     SECItem der;
9151 
9152     TraceMethodEnter(self);
9153 
9154     der = self->cert->derCert;
9155     return PyBytes_FromStringAndSize((char *)der.data, der.len);
9156 }
9157 
9158 static PyObject *
Certificate_get_ssl_trust_str(Certificate * self,void * closure)9159 Certificate_get_ssl_trust_str(Certificate *self, void *closure)
9160 {
9161     TraceMethodEnter(self);
9162 
9163     if (self->cert->trust)
9164         return cert_trust_flags(self->cert->trust->sslFlags, AsEnumDescription);
9165     else
9166         Py_RETURN_NONE;
9167 }
9168 
9169 static PyObject *
Certificate_get_email_trust_str(Certificate * self,void * closure)9170 Certificate_get_email_trust_str(Certificate *self, void *closure)
9171 {
9172     TraceMethodEnter(self);
9173 
9174     if (self->cert->trust)
9175         return cert_trust_flags(self->cert->trust->emailFlags, AsEnumDescription);
9176     else
9177         Py_RETURN_NONE;
9178 }
9179 
9180 static PyObject *
Certificate_get_signing_trust_str(Certificate * self,void * closure)9181 Certificate_get_signing_trust_str(Certificate *self, void *closure)
9182 {
9183     TraceMethodEnter(self);
9184 
9185     if (self->cert->trust)
9186         return cert_trust_flags(self->cert->trust->objectSigningFlags, AsEnumDescription);
9187     else
9188         Py_RETURN_NONE;
9189 }
9190 
9191 static PyObject *
Certificate_get_ssl_trust_flags(Certificate * self,void * closure)9192 Certificate_get_ssl_trust_flags(Certificate *self, void *closure)
9193 {
9194     TraceMethodEnter(self);
9195 
9196     if (self->cert->trust)
9197         return PyLong_FromLong(self->cert->trust->sslFlags);
9198     else
9199         Py_RETURN_NONE;
9200 }
9201 
9202 static PyObject *
Certificate_get_email_trust_flags(Certificate * self,void * closure)9203 Certificate_get_email_trust_flags(Certificate *self, void *closure)
9204 {
9205     TraceMethodEnter(self);
9206 
9207     if (self->cert->trust)
9208         return PyLong_FromLong(self->cert->trust->emailFlags);
9209     else
9210         Py_RETURN_NONE;
9211 }
9212 
9213 static PyObject *
Certificate_get_signing_trust_flags(Certificate * self,void * closure)9214 Certificate_get_signing_trust_flags(Certificate *self, void *closure)
9215 {
9216     TraceMethodEnter(self);
9217 
9218     if (self->cert->trust)
9219         return PyLong_FromLong(self->cert->trust->objectSigningFlags);
9220     else
9221         Py_RETURN_NONE;
9222 }
9223 
9224 static PyObject *
Certificate_get_subject_public_key_info(Certificate * self,void * closure)9225 Certificate_get_subject_public_key_info(Certificate *self, void *closure)
9226 {
9227     TraceMethodEnter(self);
9228 
9229     return SubjectPublicKeyInfo_new_from_CERTSubjectPublicKeyInfo(
9230                &self->cert->subjectPublicKeyInfo);
9231 }
9232 
9233 static PyObject *
Certificate_get_extensions(Certificate * self,void * closure)9234 Certificate_get_extensions(Certificate *self, void *closure)
9235 {
9236     return CERTCertExtension_tuple(self->cert->extensions, AsObject);
9237 }
9238 
9239 static PyObject *
Certificate_get_cert_type(Certificate * self,void * closure)9240 Certificate_get_cert_type(Certificate *self, void *closure)
9241 {
9242     TraceMethodEnter(self);
9243 
9244     return PyLong_FromLong(self->cert->nsCertType);
9245 }
9246 
9247 static
9248 PyGetSetDef Certificate_getseters[] = {
9249     {"valid_not_before",        (getter)Certificate_get_valid_not_before,        NULL,
9250      "certificate not valid before this time (floating point value expressed as microseconds since the epoch, midnight January 1st 1970 UTC)", NULL},
9251 
9252     {"valid_not_before_str",    (getter)Certificate_get_valid_not_before_str,    NULL,
9253      "certificate not valid before this time (string value expressed, UTC)", NULL},
9254 
9255     {"valid_not_after",         (getter)Certificate_get_valid_not_after,         NULL,
9256      "certificate not valid after this time (floating point value expressed as microseconds since the epoch, midnight January 1st 1970, UTC)", NULL},
9257 
9258     {"valid_not_after_str",     (getter)Certificate_get_valid_not_after_str,     NULL,
9259      "certificate not valid after this time (string value expressed, UTC)", NULL},
9260 
9261     {"subject",                 (getter)Certificate_get_subject,                 NULL,
9262      "certificate subject as a `DN` object", NULL},
9263 
9264     {"subject_common_name",     (getter)Certificate_get_subject_common_name,     NULL,
9265      "certificate subject", NULL},
9266 
9267     {"issuer",                  (getter)Certificate_get_issuer,                  NULL,
9268      "certificate issuer as a `DN` object",  NULL},
9269 
9270     {"version",                 (getter)Certificate_get_version,                 NULL,
9271      "certificate version",  NULL},
9272 
9273     {"serial_number",           (getter)Certificate_get_serial_number,           NULL,
9274      "certificate serial number",  NULL},
9275 
9276     {"signature_algorithm",     (getter)Certificate_get_signature_algorithm,     NULL,
9277      "certificate signature algorithm",  NULL},
9278 
9279     {"signed_data",             (getter)Certificate_get_signed_data,             NULL,
9280      "certificate signature as SignedData object",  NULL},
9281 
9282     {"der_data",                (getter)Certificate_get_der_data,                NULL,
9283      "raw certificate DER data as data buffer",  NULL},
9284 
9285     {"ssl_trust_str",           (getter)Certificate_get_ssl_trust_str,           NULL,
9286      "certificate SSL trust flags as array of strings, or None if trust is not defined",  NULL},
9287 
9288     {"email_trust_str",         (getter)Certificate_get_email_trust_str,         NULL,
9289      "certificate email trust flags as array of strings, or None if trust is not defined",  NULL},
9290 
9291     {"signing_trust_str",       (getter)Certificate_get_signing_trust_str,       NULL,
9292      "certificate object signing trust flags as array of strings, or None if trust is not defined",  NULL},
9293 
9294     {"ssl_trust_flags",           (getter)Certificate_get_ssl_trust_flags,           NULL,
9295      "certificate SSL trust flags as integer bitmask, or None if not defined",  NULL},
9296 
9297     {"email_trust_flags",         (getter)Certificate_get_email_trust_flags,         NULL,
9298      "certificate email trust flags as integer bitmask, or None if not defined",  NULL},
9299 
9300     {"signing_trust_flags",       (getter)Certificate_get_signing_trust_flags,       NULL,
9301      "certificate object signing trust flags as integer bitmask, or None if not defined",  NULL},
9302 
9303     {"subject_public_key_info", (getter)Certificate_get_subject_public_key_info, NULL,
9304      "certificate public info as SubjectPublicKeyInfo object",  NULL},
9305 
9306     {"extensions", (getter)Certificate_get_extensions, NULL,
9307      "certificate extensions as a tuple of CertificateExtension objects",  NULL},
9308 
9309     {"cert_type",               (getter)Certificate_get_cert_type,                NULL,
9310      "integer bitmask of NS_CERT_TYPE_* flags, see `nss.cert_type_flags()`",  NULL},
9311 
9312     {NULL}  /* Sentinel */
9313 };
9314 
9315 static PyMemberDef Certificate_members[] = {
9316     {NULL}  /* Sentinel */
9317 };
9318 
9319 /* ============================== Class Methods ============================= */
9320 
9321 PyDoc_STRVAR(Certificate_trust_flags_doc,
9322 "trust_flags(flags, repr_kind=AsEnumDescription) -> ['flag_name', ...]\n\
9323 \n\
9324 :Parameters:\n\
9325     flags : int\n\
9326         certificate trust integer bitmask\n\
9327     repr_kind : RepresentationKind constant\n\
9328         Specifies what the contents of the returned list will be.\n\
9329         May be one of:\n\
9330 \n\
9331         AsEnum\n\
9332             The enumerated constant as an integer value.\n\
9333         AsEnumName\n\
9334             The name of the enumerated constant as a string.\n\
9335         AsEnumDescription\n\
9336             A friendly human readable description of the enumerated constant as a string.\n\
9337 \n\
9338 Given an integer with trust flags encoded as a bitmask\n\
9339 return a sorted list of their values as specified in the repr_kind\n\
9340 \n\
9341 This is a class method.\n\
9342 ");
9343 
9344 static PyObject *
Certificate_trust_flags(PyObject * cls,PyObject * args,PyObject * kwds)9345 Certificate_trust_flags(PyObject *cls, PyObject *args, PyObject *kwds)
9346 {
9347     static char *kwlist[] = {"flags", "repr_kind", NULL};
9348     int flags = 0;
9349     RepresentationKind repr_kind = AsEnumDescription;
9350 
9351     TraceMethodEnter(cls);
9352 
9353     if (!PyArg_ParseTupleAndKeywords(args, kwds, "i|i:trust_flags", kwlist,
9354                                      &flags, &repr_kind))
9355         return NULL;
9356 
9357     return cert_trust_flags(flags, repr_kind);
9358 }
9359 
9360 PyDoc_STRVAR(Certificate_set_trust_attributes_doc,
9361 "set_trust_attributes(trust, certdb, slot, [user_data1, ...])\n\
9362 \n\
9363 :Parameters:\n\
9364     string : trust\n\
9365         NSS trust string\n\
9366     certdb : CertDB object or None\n\
9367         CertDB certificate database object, if None then the default\n\
9368         certdb will be supplied by calling `nss.get_default_certdb()`.\n\
9369     slot : `PK11Slot` object\n\
9370         The PK11 slot to use. If None defaults to internal\n\
9371         slot, see `nss.get_internal_key_slot()`\n\
9372     user_dataN : object\n\
9373         zero or more caller supplied parameters which will\n\
9374         be passed to the password callback function\n\
9375 \n\
9376 ");
9377 
9378 static PyObject *
Certificate_set_trust_attributes(Certificate * self,PyObject * args)9379 Certificate_set_trust_attributes(Certificate *self, PyObject *args)
9380 {
9381     Py_ssize_t n_base_args = 3;
9382     Py_ssize_t argc;
9383     PyObject *parse_args = NULL;
9384     PyObject *pin_args = NULL;
9385     char *trust_string = NULL;
9386     CertDB *py_certdb = NULL;
9387     CERTCertDBHandle *certdb_handle = NULL;
9388     PyObject *py_slot = Py_None;
9389     PK11SlotInfo *slot = NULL;
9390     CERTCertTrust *trust = NULL;
9391     SECStatus result = SECFailure;
9392 
9393     TraceMethodEnter(self);
9394 
9395     argc = PyTuple_Size(args);
9396     if (argc == n_base_args) {
9397         Py_INCREF(args);
9398         parse_args = args;
9399     } else {
9400         parse_args = PyTuple_GetSlice(args, 0, n_base_args);
9401     }
9402     if (!PyArg_ParseTuple(parse_args, "sO&O&:set_trust_attributes",
9403                           &trust_string,
9404                           CertDBOrNoneConvert, &py_certdb,
9405                           PK11SlotOrNoneConvert, &py_slot)) {
9406         Py_DECREF(parse_args);
9407         return NULL;
9408     }
9409     Py_DECREF(parse_args);
9410 
9411     if (py_certdb) {
9412         certdb_handle = py_certdb->handle;
9413     } else {
9414         certdb_handle = CERT_GetDefaultCertDB();
9415     }
9416 
9417     if (PyNone_Check(py_slot)) {
9418 	slot = PK11_GetInternalKeySlot();
9419     } else {
9420         slot = ((PK11Slot *)py_slot)->slot;
9421     }
9422 
9423     pin_args = PyTuple_GetSlice(args, n_base_args, argc);
9424 
9425     if ((trust = (CERTCertTrust *)PORT_ZAlloc(sizeof(CERTCertTrust))) == NULL) {
9426         PyErr_NoMemory();
9427         goto exit;
9428     }
9429 
9430     if ((result = CERT_DecodeTrustString(trust, trust_string)) != SECSuccess) {
9431         set_nspr_error("cannot decode trust string '%s'", trust_string);
9432         goto exit;
9433     }
9434 
9435     /*
9436      * CERT_ChangeCertTrust API does not have a way to pass in a
9437      * context, so NSS can't prompt for the password if it needs to.
9438      * check to see if the failure was token not logged in and log in
9439      * if need be.
9440      */
9441     Py_BEGIN_ALLOW_THREADS
9442     if ((result = CERT_ChangeCertTrust(certdb_handle, self->cert, trust)) != SECSuccess) {
9443 	if (PORT_GetError() == SEC_ERROR_TOKEN_NOT_LOGGED_IN) {
9444 	    if ((result = PK11_Authenticate(slot, PR_TRUE, pin_args)) != SECSuccess) {
9445                 set_nspr_error("Unable to authenticate");
9446             } else {
9447                 if ((result = CERT_ChangeCertTrust(certdb_handle, self->cert, trust)) != SECSuccess) {
9448                     set_nspr_error(NULL);
9449                 }
9450             }
9451         }
9452     }
9453     Py_END_ALLOW_THREADS
9454 
9455  exit:
9456     Py_DECREF(pin_args);
9457     PORT_Free(trust);
9458     if (result == SECSuccess) {
9459         Py_RETURN_NONE;
9460     } else {
9461         return NULL;
9462     }
9463 }
9464 
9465 PyDoc_STRVAR(Certificate_find_kea_type_doc,
9466 "find_kea_type() -> kea_type\n\
9467 Returns key exchange type of the keys in an SSL server certificate.\n\
9468 \n\
9469 May be one of the following:\n\
9470     - ssl_kea_null\n\
9471     - ssl_kea_rsa\n\
9472     - ssl_kea_dh\n\
9473     - ssl_kea_fortezza (deprecated)\n\
9474     - ssl_kea_ecdh\n\
9475 "
9476 );
9477 static PyObject *
Certificate_find_kea_type(Certificate * self,PyObject * args)9478 Certificate_find_kea_type(Certificate *self, PyObject *args)
9479 {
9480     TraceMethodEnter(self);
9481 
9482     return PyLong_FromLong(NSS_FindCertKEAType(self->cert));
9483 }
9484 
9485 
9486 PyDoc_STRVAR(Certificate_make_ca_nickname_doc,
9487 "make_ca_nickname() -> string\n\
9488 Returns a nickname for the certificate guaranteed to be unique\n\
9489 within the the current NSS database.\n\
9490 \n\
9491 The nickname is composed thusly:\n\
9492 \n\
9493 A. Establish a name by trying in order:\n\
9494 \n\
9495    1. subject's common name (i.e. CN)\n\
9496    2. subject's organizational unit name (i.e. OU)\n\
9497 \n\
9498 B. Establish a realm by trying in order:\n\
9499 \n\
9500    1. issuer's organization name (i.e. O)\n\
9501    2. issuer's distinguished name (i.e. DN)\n\
9502    3. set to \"Unknown CA\"\n\
9503 \n\
9504 C. If name exists the nickname will be \"name - realm\",\n\
9505    else the nickname will be \"realm\"\n\
9506 \n\
9507 D. Then the nickname will be tested for existence in the database.\n\
9508    If it does not exist it will be returned as the nickname.\n\
9509    Else a loop is entered where the nickname will have \" #%d\" appended\n\
9510    to it where %d is an integer beginning at 1. The generated nickname is\n\
9511    tested for existence in the dabase until a unique name is found.\n\
9512 \n\
9513 "
9514 );
9515 static PyObject *
Certificate_make_ca_nickname(Certificate * self,PyObject * args)9516 Certificate_make_ca_nickname(Certificate *self, PyObject *args)
9517 {
9518     char *nickname = NULL;
9519     PyObject *py_nickname = NULL;
9520 
9521     TraceMethodEnter(self);
9522 
9523     if ((nickname = CERT_MakeCANickname(self->cert)) == NULL) {
9524         return set_nspr_error(NULL);
9525     }
9526 
9527     py_nickname = PyUnicode_FromString(nickname);
9528     PR_smprintf_free(nickname);
9529     return py_nickname;
9530 }
9531 
9532 
9533 PyDoc_STRVAR(Certificate_verify_hostname_doc,
9534 "verify_hostname(hostname) -> bool\n\
9535 \n\
9536 A restricted regular expression syntax is used to test if the common\n\
9537 name specified in the subject DN of the certificate is a match,\n\
9538 returning True if so, False otherwise.\n\
9539 \n\
9540 The regular expression systax is:\n\
9541     \\*\n\
9542         matches anything\n\
9543     \\?\n\
9544         matches one character\n\
9545     \\\\ (backslash)\n\
9546         escapes a special character\n\
9547     \\$\n\
9548          matches the end of the string\n\
9549     [abc]\n\
9550         matches one occurrence of a, b, or c. The only character\n\
9551         that needs to be escaped in this is ], all others are not special.\n\
9552     [a-z]\n\
9553         matches any character between a and z\n\
9554     [^az]\n\
9555         matches any character except a or z\n\
9556     \\~\n\
9557         followed by another shell expression removes any pattern matching\n\
9558         the shell expression from the match list\n\
9559     (foo|bar)\n\
9560         matches either the substring foo or the substring bar.\n\
9561         These can be shell expressions as well.\n\
9562 ");
9563 
9564 static PyObject *
Certificate_verify_hostname(Certificate * self,PyObject * args)9565 Certificate_verify_hostname(Certificate *self, PyObject *args)
9566 {
9567     char *hostname;
9568     SECStatus sec_status;
9569 
9570     TraceMethodEnter(self);
9571 
9572     if (!PyArg_ParseTuple(args, "s:verify_hostname", &hostname))
9573         return NULL;
9574 
9575     sec_status = CERT_VerifyCertName(self->cert, hostname);
9576 
9577     if (sec_status == SECSuccess)
9578         Py_RETURN_TRUE;
9579     else
9580         Py_RETURN_FALSE;
9581 }
9582 
9583 PyDoc_STRVAR(Certificate_has_signer_in_ca_names_doc,
9584 "has_signer_in_ca_names(ca_names) -> bool\n\
9585 \n\
9586 :Parameters:\n\
9587     ca_names : (SecItem, ...)\n\
9588         Sequence of CA distinguished names. Each item in the sequence must\n\
9589         be a SecItem object containing a distinguished name.\n\
9590 \n\
9591 Returns True if any of the signers in the certificate chain for a\n\
9592 specified certificate are in the list of CA names, False\n\
9593 otherwise.\n\
9594 ");
9595 
9596 static PyObject *
Certificate_has_signer_in_ca_names(Certificate * self,PyObject * args)9597 Certificate_has_signer_in_ca_names(Certificate *self, PyObject *args)
9598 {
9599     PyObject *py_ca_names = NULL;
9600     CERTDistNames *ca_names = NULL;
9601     SECStatus sec_status;
9602 
9603     TraceMethodEnter(self);
9604 
9605     if (!PyArg_ParseTuple(args, "O:has_signer_in_ca_names",
9606                           &py_ca_names))
9607         return NULL;
9608 
9609     if ((ca_names = cert_distnames_as_CERTDistNames(py_ca_names)) == NULL) {
9610         return NULL;
9611     }
9612 
9613     sec_status = NSS_CmpCertChainWCANames(self->cert, ca_names);
9614     CERT_FreeDistNames(ca_names);
9615 
9616     if (sec_status == SECSuccess)
9617         Py_RETURN_TRUE;
9618     else
9619         Py_RETURN_FALSE;
9620 }
9621 
9622 PyDoc_STRVAR(Certificate_check_valid_times_doc,
9623 "check_valid_times(time=now, allow_override=False) --> validity\n\
9624 \n\
9625 :Parameters:\n\
9626     time : number or None\n\
9627         an optional point in time as number of microseconds\n\
9628         since the NSPR epoch, midnight (00:00:00) 1 January\n\
9629         1970 UTC, either as an integer or a float. If time \n\
9630         is None the current time is used.\n\
9631     allow_override : bool\n\
9632         If True then check to see if the invalidity has\n\
9633         been overridden by the user, defaults to False.\n\
9634 \n\
9635 Checks whether a specified time is within a certificate's validity\n\
9636 period.\n\
9637 \n\
9638 Returns one of:\n\
9639 \n\
9640 - secCertTimeValid\n\
9641 - secCertTimeExpired\n\
9642 - secCertTimeNotValidYet\n\
9643 ");
9644 
9645 static PyObject *
Certificate_check_valid_times(Certificate * self,PyObject * args,PyObject * kwds)9646 Certificate_check_valid_times(Certificate *self, PyObject *args, PyObject *kwds)
9647 {
9648     static char *kwlist[] = {"time", "allow_override", NULL};
9649     PRTime pr_time = 0;
9650     PyObject *py_allow_override = NULL;
9651     PRBool allow_override = PR_FALSE;
9652     SECCertTimeValidity validity;
9653 
9654     TraceMethodEnter(self);
9655 
9656     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O&O!:check_valid_times", kwlist,
9657                                      PRTimeConvert, &pr_time,
9658                                      &PyBool_Type, &py_allow_override))
9659         return NULL;
9660 
9661     if (!pr_time) {
9662         pr_time = PR_Now();
9663     }
9664 
9665     if (py_allow_override) {
9666         allow_override = PyBoolAsPRBool(py_allow_override);
9667     }
9668 
9669     validity = CERT_CheckCertValidTimes(self->cert, pr_time, allow_override);
9670 
9671     return PyLong_FromLong(validity);
9672 }
9673 
9674 PyDoc_STRVAR(Certificate_is_ca_cert_doc,
9675 "is_ca_cert(return_cert_type=False) -> boolean\n\
9676 is_ca_cert(True) -> boolean, cert_type\n\
9677 \n\
9678 :Parameters:\n\
9679     return_cert_type : boolean\n\
9680         If True returns both boolean result and certficate\n\
9681         type bitmask. If False return only boolean result\n\
9682 \n\
9683 Returns True if the cert is a CA cert, False otherwise.\n\
9684 \n\
9685 The function optionally can return a bitmask of NS_CERT_TYPE_*\n\
9686 flags if return_cert_type is True. This is the updated cert type\n\
9687 after applying logic in the context of deciding if the cert is a\n\
9688 CA cert or not. Hint: the cert_type value can be converted to text\n\
9689 with `nss.cert_type_flags()`. Hint: the unmodified cert type flags\n\
9690 can be obtained with the `Certificate.cert_type` property.\n\
9691 \n\
9692 ");
9693 static PyObject *
Certificate_is_ca_cert(Certificate * self,PyObject * args,PyObject * kwds)9694 Certificate_is_ca_cert(Certificate *self, PyObject *args, PyObject *kwds)
9695 {
9696     static char *kwlist[] = {"return_cert_type", NULL};
9697     int return_cert_type = false;
9698     PRBool is_ca = PR_FALSE;
9699     unsigned int cert_type = 0;
9700 
9701     TraceMethodEnter(self);
9702 
9703     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:is_ca_cert", kwlist,
9704                                      &return_cert_type))
9705         return NULL;
9706 
9707     is_ca = CERT_IsCACert(self->cert, return_cert_type ? &cert_type : NULL);
9708 
9709 
9710     if (return_cert_type) {
9711         return Py_BuildValue("NI", PyBool_FromLong(is_ca), cert_type);
9712     } else {
9713         return PyBool_FromLong(is_ca);
9714     }
9715 }
9716 
9717 PyDoc_STRVAR(Certificate_verify_now_doc,
9718 "verify_now(certdb, check_sig, required_usages, [user_data1, ...]) -> valid_usages\n\
9719 \n\
9720 :Parameters:\n\
9721     certdb : CertDB object\n\
9722         CertDB certificate database object\n\
9723     check_sig : bool\n\
9724         True if certificate signatures should be checked\n\
9725     required_usages : integer\n\
9726         A bitfield of all cert usages that are required for verification\n\
9727         to succeed. If zero return all possible valid usages.\n\
9728     user_dataN : object\n\
9729         zero or more caller supplied parameters which will\n\
9730         be passed to the password callback function\n\
9731 \n\
9732 Verify a certificate by checking if it's valid and that we\n\
9733 trust the issuer.\n\
9734 \n\
9735 Possible usage bitfield values are:\n\
9736     - certificateUsageCheckAllUsages\n\
9737     - certificateUsageSSLClient\n\
9738     - certificateUsageSSLServer\n\
9739     - certificateUsageSSLServerWithStepUp\n\
9740     - certificateUsageSSLCA\n\
9741     - certificateUsageEmailSigner\n\
9742     - certificateUsageEmailRecipient\n\
9743     - certificateUsageObjectSigner\n\
9744     - certificateUsageUserCertImport\n\
9745     - certificateUsageVerifyCA\n\
9746     - certificateUsageProtectedObjectSigner\n\
9747     - certificateUsageStatusResponder\n\
9748     - certificateUsageAnyCA\n\
9749 \n\
9750 Returns valid_usages, a bitfield of certificate usages.  If\n\
9751 required_usages is non-zero, the returned bitmap is only for those\n\
9752 required usages, otherwise it is for all possible usages.\n\
9753 \n\
9754 Hint: You can obtain a printable representation of the usage flags\n\
9755 via `cert_usage_flags`.\n\
9756 \n\
9757 Note: See the `Certificate.verify` documentation for details on how\n\
9758 the Certificate verification functions handle errors.\n\
9759 ");
9760 
9761 static PyObject *
Certificate_verify_now(Certificate * self,PyObject * args)9762 Certificate_verify_now(Certificate *self, PyObject *args)
9763 {
9764     Py_ssize_t n_base_args = 3;
9765     Py_ssize_t argc;
9766     PyObject *parse_args = NULL;
9767     PyObject *pin_args = NULL;
9768     CertDB *py_certdb = NULL;
9769     PyObject *py_check_sig = NULL;
9770     PRBool check_sig = 0;
9771     long required_usages = 0;
9772     SECCertificateUsage returned_usages = 0;
9773 
9774     TraceMethodEnter(self);
9775 
9776     argc = PyTuple_Size(args);
9777     if (argc == n_base_args) {
9778         Py_INCREF(args);
9779         parse_args = args;
9780     } else {
9781         parse_args = PyTuple_GetSlice(args, 0, n_base_args);
9782     }
9783     if (!PyArg_ParseTuple(parse_args, "O!O!l:verify_now",
9784                           &CertDBType, &py_certdb,
9785                           &PyBool_Type, &py_check_sig,
9786                           &required_usages)) {
9787         Py_DECREF(parse_args);
9788         return NULL;
9789     }
9790     Py_DECREF(parse_args);
9791 
9792     check_sig = PyBoolAsPRBool(py_check_sig);
9793     pin_args = PyTuple_GetSlice(args, n_base_args, argc);
9794 
9795     Py_BEGIN_ALLOW_THREADS
9796     if (CERT_VerifyCertificateNow(py_certdb->handle, self->cert, check_sig,
9797                                   required_usages, pin_args, &returned_usages) != SECSuccess) {
9798 	Py_BLOCK_THREADS
9799         Py_DECREF(pin_args);
9800         return set_cert_verify_error(returned_usages, NULL, NULL);
9801     }
9802     Py_END_ALLOW_THREADS
9803     Py_DECREF(pin_args);
9804 
9805     return PyLong_FromLong(returned_usages);
9806 }
9807 
9808 PyDoc_STRVAR(Certificate_verify_doc,
9809 "verify(certdb, check_sig, required_usages, time, [user_data1, ...]) -> valid_usages\n\
9810 \n\
9811 :Parameters:\n\
9812     certdb : CertDB object\n\
9813         CertDB certificate database object\n\
9814     check_sig : bool\n\
9815         True if certificate signatures should be checked\n\
9816     required_usages : integer\n\
9817         A bitfield of all cert usages that are required for verification\n\
9818         to succeed. If zero return all possible valid usages.\n\
9819     time : number or None\n\
9820         an optional point in time as number of microseconds\n\
9821         since the NSPR epoch, midnight (00:00:00) 1 January\n\
9822         1970 UTC, either as an integer or a float. If time \n\
9823         is None the current time is used.\n\
9824     user_dataN : object\n\
9825         zero or more caller supplied parameters which will\n\
9826         be passed to the password callback function\n\
9827 \n\
9828 Verify a certificate by checking if it's valid and that we\n\
9829 trust the issuer.\n\
9830 \n\
9831 Possible usage bitfield values are:\n\
9832     - certificateUsageCheckAllUsages\n\
9833     - certificateUsageSSLClient\n\
9834     - certificateUsageSSLServer\n\
9835     - certificateUsageSSLServerWithStepUp\n\
9836     - certificateUsageSSLCA\n\
9837     - certificateUsageEmailSigner\n\
9838     - certificateUsageEmailRecipient\n\
9839     - certificateUsageObjectSigner\n\
9840     - certificateUsageUserCertImport\n\
9841     - certificateUsageVerifyCA\n\
9842     - certificateUsageProtectedObjectSigner\n\
9843     - certificateUsageStatusResponder\n\
9844     - certificateUsageAnyCA\n\
9845 \n\
9846 Returns valid_usages, a bitfield of certificate usages.\n\
9847 \n\
9848 If required_usages is non-zero, the returned bitmap is only for those\n\
9849 required usages, otherwise it is for all possible usages.\n\
9850 \n\
9851 Hint: You can obtain a printable representation of the usage flags\n\
9852 via `cert_usage_flags`.\n\
9853 \n\
9854 Note: Anytime a NSPR or NSS function returns an error in python-nss it\n\
9855 raises a NSPRError exception. When an exception is raised the normal\n\
9856 return values are discarded because the flow of control continues at\n\
9857 the first except block prepared to catch the exception. Normally this\n\
9858 is what is desired because the return values would be invalid due to\n\
9859 the error. However the certificate verification functions are an\n\
9860 exception (no pun intended). An error might be returned indicating the\n\
9861 cert failed verification but you may still need access to the returned\n\
9862 usage bitmask and the log (if using the log variant). To handle this a\n\
9863 special error exception `CertVerifyError` (derived from `NSPRError`)\n\
9864 is defined which in addition to the normal NSPRError fields will also\n\
9865 contain the returned usages and optionally the CertVerifyLog\n\
9866 object. If no exception is raised these are returned as normal return\n\
9867 values.\n\
9868 ");
9869 
9870 static PyObject *
Certificate_verify(Certificate * self,PyObject * args)9871 Certificate_verify(Certificate *self, PyObject *args)
9872 {
9873     Py_ssize_t n_base_args = 4;
9874     Py_ssize_t argc;
9875     PyObject *parse_args = NULL;
9876     PyObject *pin_args = NULL;
9877     CertDB *py_certdb = NULL;
9878     PyObject *py_check_sig = NULL;
9879     PRBool check_sig = 0;
9880     PRTime pr_time = 0;
9881     long required_usages = 0;
9882     SECCertificateUsage returned_usages = 0;
9883 
9884     TraceMethodEnter(self);
9885 
9886     argc = PyTuple_Size(args);
9887     if (argc == n_base_args) {
9888         Py_INCREF(args);
9889         parse_args = args;
9890     } else {
9891         parse_args = PyTuple_GetSlice(args, 0, n_base_args);
9892     }
9893     if (!PyArg_ParseTuple(parse_args, "O!O!lO&:verify",
9894                           &CertDBType, &py_certdb,
9895                           &PyBool_Type, &py_check_sig,
9896                           &required_usages,
9897                           PRTimeConvert, &pr_time)) {
9898         Py_DECREF(parse_args);
9899         return NULL;
9900     }
9901     Py_DECREF(parse_args);
9902 
9903     check_sig = PyBoolAsPRBool(py_check_sig);
9904     pin_args = PyTuple_GetSlice(args, n_base_args, argc);
9905 
9906     Py_BEGIN_ALLOW_THREADS
9907     if (CERT_VerifyCertificate(py_certdb->handle, self->cert, check_sig,
9908                                required_usages, pr_time, pin_args,
9909                                NULL, &returned_usages) != SECSuccess) {
9910 	Py_BLOCK_THREADS
9911         Py_DECREF(pin_args);
9912         return set_cert_verify_error(returned_usages, NULL, NULL);
9913     }
9914     Py_END_ALLOW_THREADS
9915     Py_DECREF(pin_args);
9916 
9917     return PyLong_FromLong(returned_usages);
9918 }
9919 
9920 PyDoc_STRVAR(Certificate_verify_with_log_doc,
9921 "verify_with_log(certdb, check_sig, required_usages, time, [user_data1, ...]) -> valid_usages, log\n\
9922 \n\
9923 :Parameters:\n\
9924     certdb : CertDB object\n\
9925         CertDB certificate database object\n\
9926     check_sig : bool\n\
9927         True if certificate signatures should be checked\n\
9928     required_usages : integer\n\
9929         A bitfield of all cert usages that are required for verification\n\
9930         to succeed. If zero return all possible valid usages.\n\
9931     time : number or None\n\
9932         an optional point in time as number of microseconds\n\
9933         since the NSPR epoch, midnight (00:00:00) 1 January\n\
9934         1970 UTC, either as an integer or a float. If time \n\
9935         is None the current time is used.\n\
9936     user_dataN : object\n\
9937         zero or more caller supplied parameters which will\n\
9938         be passed to the password callback function\n\
9939 \n\
9940 Verify a certificate by checking if it's valid and that we\n\
9941 trust the issuer.\n\
9942 \n\
9943 Possible usage bitfield values are:\n\
9944     - certificateUsageCheckAllUsages\n\
9945     - certificateUsageSSLClient\n\
9946     - certificateUsageSSLServer\n\
9947     - certificateUsageSSLServerWithStepUp\n\
9948     - certificateUsageSSLCA\n\
9949     - certificateUsageEmailSigner\n\
9950     - certificateUsageEmailRecipient\n\
9951     - certificateUsageObjectSigner\n\
9952     - certificateUsageUserCertImport\n\
9953     - certificateUsageVerifyCA\n\
9954     - certificateUsageProtectedObjectSigner\n\
9955     - certificateUsageStatusResponder\n\
9956     - certificateUsageAnyCA\n\
9957 \n\
9958 Returns valid_usages, a bitfield of certificate usages and a `nss.CertVerifyLog`\n\
9959 object with diagnostic information detailing the reasons for a validation failure.\n\
9960 \n\
9961 If required_usages is non-zero, the returned bitmap is only for those\n\
9962 required usages, otherwise it is for all possible usages.\n\
9963 \n\
9964 Hint: You can obtain a printable representation of the usage flags\n\
9965 via `cert_usage_flags`.\n\
9966 \n\
9967 Note: See the `Certificate.verify` documentation for details on how\n\
9968 the Certificate verification functions handle errors.\n\
9969 ");
9970 
9971 static PyObject *
Certificate_verify_with_log(Certificate * self,PyObject * args)9972 Certificate_verify_with_log(Certificate *self, PyObject *args)
9973 {
9974     Py_ssize_t n_base_args = 4;
9975     Py_ssize_t argc;
9976     PyObject *parse_args = NULL;
9977     PyObject *pin_args = NULL;
9978     CertDB *py_certdb = NULL;
9979     PyObject *py_check_sig = NULL;
9980     PRBool check_sig = 0;
9981     PRTime pr_time = 0;
9982     CertVerifyLog *py_log = NULL;
9983     long required_usages = 0;
9984     SECCertificateUsage returned_usages = 0;
9985 
9986     TraceMethodEnter(self);
9987 
9988     argc = PyTuple_Size(args);
9989     if (argc == n_base_args) {
9990         Py_INCREF(args);
9991         parse_args = args;
9992     } else {
9993         parse_args = PyTuple_GetSlice(args, 0, n_base_args);
9994     }
9995     if (!PyArg_ParseTuple(parse_args, "O!O!lO&:verify_with_log",
9996                           &CertDBType, &py_certdb,
9997                           &PyBool_Type, &py_check_sig,
9998                           &required_usages,
9999                           PRTimeConvert, &pr_time)) {
10000         Py_DECREF(parse_args);
10001         return NULL;
10002     }
10003     Py_DECREF(parse_args);
10004 
10005     check_sig = PyBoolAsPRBool(py_check_sig);
10006     pin_args = PyTuple_GetSlice(args, n_base_args, argc);
10007 
10008     if ((py_log = (CertVerifyLog *)CertVerifyLog_new(&CertVerifyLogType, NULL, NULL)) == NULL) {
10009         Py_DECREF(pin_args);
10010         return NULL;
10011     }
10012 
10013     Py_BEGIN_ALLOW_THREADS
10014     if (CERT_VerifyCertificate(py_certdb->handle, self->cert, check_sig,
10015                                required_usages, pr_time, pin_args,
10016                                &py_log->log, &returned_usages) != SECSuccess) {
10017 	Py_BLOCK_THREADS
10018         Py_DECREF(pin_args);
10019         return set_cert_verify_error(returned_usages, (PyObject *)py_log, NULL);
10020     }
10021     Py_END_ALLOW_THREADS
10022     Py_DECREF(pin_args);
10023 
10024     return Py_BuildValue("KN", returned_usages, py_log);
10025 }
10026 
10027 PyDoc_STRVAR(Certificate_check_ocsp_status_doc,
10028 "check_ocsp_status(certdb, time, [user_data1, ...]) -> boolean\n\
10029 \n\
10030 :Parameters:\n\
10031     certdb : CertDB object\n\
10032         CertDB certificate database object.\n\
10033     time : number or None\n\
10034         Time for which status is to be determined.\n\
10035         Time as number of microseconds since the NSPR epoch, midnight\n\
10036         (00:00:00) 1 January 1970 UTC, either as an integer or a\n\
10037         float. If time is None the current time is used.\n\
10038     user_dataN : object\n\
10039         zero or more caller supplied parameters which will\n\
10040         be passed to the password callback function\n\
10041 \n\
10042 Checks the status of a certificate via OCSP.  Will only check status for\n\
10043 a certificate that has an AIA (Authority Information Access) extension\n\
10044 for OCSP or when a \"default responder\" is specified and enabled.\n\
10045 (If no AIA extension for OCSP and no default responder in place, the\n\
10046 cert is considered to have a good status.\n\
10047 \n\
10048 Returns True if an approved OCSP responder knows the cert\n\
10049 and returns a non-revoked status for it. Otherwise a `error.NSPRError`\n\
10050 is raised and it's error_code property may be one of the following:\n\
10051 \n\
10052     - SEC_ERROR_OCSP_BAD_HTTP_RESPONSE\n\
10053     - SEC_ERROR_OCSP_FUTURE_RESPONSE\n\
10054     - SEC_ERROR_OCSP_MALFORMED_REQUEST\n\
10055     - SEC_ERROR_OCSP_MALFORMED_RESPONSE\n\
10056     - SEC_ERROR_OCSP_OLD_RESPONSE\n\
10057     - SEC_ERROR_OCSP_REQUEST_NEEDS_SIG\n\
10058     - SEC_ERROR_OCSP_SERVER_ERROR\n\
10059     - SEC_ERROR_OCSP_TRY_SERVER_LATER\n\
10060     - SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST\n\
10061     - SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE\n\
10062     - SEC_ERROR_OCSP_UNKNOWN_CERT\n\
10063     - SEC_ERROR_OCSP_UNKNOWN_RESPONSE_STATUS\n\
10064     - SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE\n\
10065 \n\
10066     - SEC_ERROR_BAD_SIGNATURE\n\
10067     - SEC_ERROR_CERT_BAD_ACCESS_LOCATION\n\
10068     - SEC_ERROR_INVALID_TIME\n\
10069     - SEC_ERROR_REVOKED_CERTIFICATE\n\
10070     - SEC_ERROR_UNKNOWN_ISSUER\n\
10071     - SEC_ERROR_UNKNOWN_SIGNER\n\
10072 \n\
10073 Other errors are possible failures in cert verification\n\
10074 (e.g. SEC_ERROR_REVOKED_CERTIFICATE, SEC_ERROR_UNTRUSTED_ISSUER) when\n\
10075 verifying the signer's cert, or other low-level problems.\n\
10076 ");
10077 static PyObject *
Certificate_check_ocsp_status(Certificate * self,PyObject * args)10078 Certificate_check_ocsp_status(Certificate *self, PyObject *args)
10079 {
10080     Py_ssize_t n_base_args = 2;
10081     CertDB *py_certdb = NULL;
10082     Py_ssize_t argc;
10083     PyObject *parse_args = NULL;
10084     PyObject *pin_args = NULL;
10085 
10086     PRTime pr_time = 0;
10087 
10088     TraceMethodEnter(self);
10089 
10090     argc = PyTuple_Size(args);
10091     if (argc == n_base_args) {
10092         Py_INCREF(args);
10093         parse_args = args;
10094     } else {
10095         parse_args = PyTuple_GetSlice(args, 0, n_base_args);
10096     }
10097     if (!PyArg_ParseTuple(args, "O!O&:check_ocsp_status",
10098                           &CertDBType, &py_certdb,
10099                           PRTimeConvert, &pr_time)) {
10100         Py_DECREF(parse_args);
10101         return NULL;
10102     }
10103     Py_DECREF(parse_args);
10104 
10105     pin_args = PyTuple_GetSlice(args, n_base_args, argc);
10106 
10107     Py_BEGIN_ALLOW_THREADS
10108     if (CERT_CheckOCSPStatus(py_certdb->handle, self->cert,
10109                              pr_time, pin_args) != SECSuccess) {
10110 	Py_BLOCK_THREADS
10111         Py_DECREF(pin_args);
10112         return set_nspr_error(NULL);
10113     }
10114     Py_END_ALLOW_THREADS
10115 
10116     Py_DECREF(pin_args);
10117     Py_RETURN_TRUE;
10118 }
10119 
10120 PyDoc_STRVAR(Certificate_get_extension_doc,
10121 "get_extension(oid) -> `CertificateExtension`\n\
10122 \n\
10123 Given an oid identifying the extension try to locate it in the\n\
10124 certificate and return it as generic `CertificateExtension` object. If\n\
10125 the extension is not present raise a KeyError.\n\
10126 \n\
10127 The generic `CertificateExtension` object is not terribly useful on\n\
10128 it's own, howerver it's value property can be used to intialize\n\
10129 instances of a class representing the extension.  Or it may be passed\n\
10130 to functions that convert the value into some other usable format.\n\
10131 Although one might believe this function should do these conversions\n\
10132 for you automatically there are too many possible variations. Plus one\n\
10133 might simple be interested to know if an extension is present or\n\
10134 not. So why perform conversion work that might not be needed or might\n\
10135 not be in the format needed? Therefore this function is just one\n\
10136 simple element in a larger toolbox. Below are some suggestions on how\n\
10137 to convert the generic `CertificateExtension` object (this list may\n\
10138 not be complete).\n\
10139 \n\
10140     SEC_OID_PKCS12_KEY_USAGE\n\
10141         `x509_key_usage()`\n\
10142     SEC_OID_X509_SUBJECT_KEY_ID\n\
10143         `SecItem.der_to_hex()`\n\
10144     SEC_OID_X509_CRL_DIST_POINTS\n\
10145         `CRLDistributionPts()`\n\
10146     case SEC_OID_X509_AUTH_KEY_ID\n\
10147         `AuthKeyID()`\n\
10148     SEC_OID_X509_EXT_KEY_USAGE\n\
10149         `x509_ext_key_usage()`\n\
10150     SEC_OID_X509_BASIC_CONSTRAINTS\n\
10151         `BasicConstraints()`\n\
10152     SEC_OID_X509_SUBJECT_ALT_NAME\n\
10153         `x509_alt_name()`\n\
10154     SEC_OID_X509_ISSUER_ALT_NAME\n\
10155         `x509_alt_name()`\n\
10156 \n\
10157 :Parameters:\n\
10158      oid : may be one of integer, string, SecItem\n\
10159          The OID of the certification extension to retreive\n\
10160          May be one of:\n\
10161 \n\
10162          * integer: A SEC OID enumeration constant (i.e. SEC_OID\\_*)\n\
10163            for example SEC_OID_X509_BASIC_CONSTRAINTS.\n\
10164          * string: A string either the OID name, with or without the SEC_OID\\_\n\
10165            prefix (e.g. \"SEC_OID_X509_BASIC_CONSTRAINTS\" or \"X509_BASIC_CONSTRAINTS\")\n\
10166            or as the dotted decimal representation, for example\n\
10167            'OID.2 5 29 19'. Case is not significant for either form.\n\
10168          * SecItem: A SecItem object encapsulating the OID in \n\
10169            DER format.\n\
10170 \n\
10171 :returns:\n\
10172     generic `CertificateExtension` object\n\
10173 \n\
10174 ");
10175 
10176 static PyObject *
Certificate_get_extension(Certificate * self,PyObject * args,PyObject * kwds)10177 Certificate_get_extension(Certificate *self, PyObject *args, PyObject *kwds)
10178 {
10179     static char *kwlist[] = {"oid", NULL};
10180     PyObject *py_oid;
10181     SECOidTag oid_tag = SEC_OID_UNKNOWN;
10182     SECOidTag cur_oid_tag = SEC_OID_UNKNOWN;
10183     CERTCertExtension **extensions = NULL;
10184     CERTCertExtension *cur_extension = NULL, *extension = NULL;
10185 
10186     TraceMethodEnter(self);
10187 
10188     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:get_extension", kwlist,
10189                                      &py_oid))
10190         return NULL;
10191 
10192     if ((oid_tag = get_oid_tag_from_object(py_oid)) == -1) {
10193         return NULL;
10194     }
10195 
10196     extension = NULL;
10197     for (extensions = self->cert->extensions; extensions && *extensions; extensions++) {
10198         cur_extension = *extensions;
10199 
10200         cur_oid_tag = SECOID_FindOIDTag(&cur_extension->id);
10201 
10202         if (cur_oid_tag == SEC_OID_UNKNOWN) {
10203             continue;
10204         }
10205 
10206         if (oid_tag == cur_oid_tag) {
10207             extension = cur_extension;
10208             break;
10209         }
10210 
10211     }
10212 
10213     if (extension == NULL) {
10214         PyObject *py_oid_name = NULL;
10215         PyObject *py_oid_name_utf8 = NULL;
10216 
10217         if ((py_oid_name = oid_tag_to_pystr_name(oid_tag)) == NULL) {
10218             py_oid_name = PyObject_String(py_oid);
10219         }
10220         py_oid_name_utf8 = PyBaseString_UTF8(py_oid_name, "oid");
10221         PyErr_Format(PyExc_KeyError, "no extension with OID %s found",
10222                      PyBytes_AsString(py_oid_name_utf8));
10223         Py_DECREF(py_oid_name);
10224         Py_XDECREF(py_oid_name_utf8);
10225         return NULL;
10226     }
10227 
10228     return CertificateExtension_new_from_CERTCertExtension(extension);
10229 
10230 }
10231 
10232 PyDoc_STRVAR(Certificate_get_cert_chain_doc,
10233 "get_cert_chain(time=now, usages=certUsageAnyCA) -> (`Certificate`, ...)\n\
10234 \n\
10235 :Parameters:\n\
10236     time : number or None\n\
10237         an optional point in time as number of microseconds\n\
10238         since the NSPR epoch, midnight (00:00:00) 1 January\n\
10239         1970 UTC, either as an integer or a float. If time \n\
10240         is None the current time is used.\n\
10241     usages : integer\n\
10242         a certUsage* enumerated constant\n\
10243 \n\
10244 Returns a tuple of `Certificate` objects.\n\
10245 ");
10246 
10247 static PyObject *
Certificate_get_cert_chain(Certificate * self,PyObject * args,PyObject * kwds)10248 Certificate_get_cert_chain(Certificate *self, PyObject *args, PyObject *kwds)
10249 {
10250     static char *kwlist[] = {"time", "usages", NULL};
10251     PRTime pr_time = 0;
10252     int usages = certUsageAnyCA;
10253     CERTCertList *cert_list = NULL;
10254     PyObject *tuple = NULL;
10255 
10256     TraceMethodEnter(self);
10257 
10258     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O&i:get_cert_chain", kwlist,
10259                                      PRTimeConvert, &pr_time, &usages))
10260         return NULL;
10261 
10262     if ((cert_list = CERT_GetCertChainFromCert(self->cert, pr_time, usages)) == NULL) {
10263         return set_nspr_error(NULL);
10264     }
10265 
10266     tuple = CERTCertList_to_tuple(cert_list, true);
10267     CERT_DestroyCertList(cert_list);
10268     return tuple;
10269 }
10270 
10271 static PyObject *
Certificate_summary_format_lines(Certificate * self,int level,PyObject * lines)10272 Certificate_summary_format_lines(Certificate *self, int level, PyObject *lines)
10273 {
10274     PyObject *obj = NULL;
10275     PyObject *obj1 = NULL;
10276     PyObject *obj2 = NULL;
10277 
10278     if ((obj = Certificate_get_subject(self, NULL)) == NULL) {
10279         goto fail;
10280     }
10281     FMT_OBJ_AND_APPEND(lines, _("Subject"), obj, level, fail);
10282     Py_CLEAR(obj);
10283 
10284     if ((obj = Certificate_get_issuer(self, NULL)) == NULL) {
10285         goto fail;
10286     }
10287     FMT_OBJ_AND_APPEND(lines, _("Issuer"), obj, level, fail);
10288     Py_CLEAR(obj);
10289 
10290     if ((obj1 = Certificate_get_valid_not_before_str(self, NULL)) == NULL) {
10291         goto fail;
10292     }
10293     if ((obj2 = Certificate_get_valid_not_after_str(self, NULL)) == NULL) {
10294         goto fail;
10295     }
10296     if ((obj = obj_sprintf("[%s] - [%s]", obj1, obj2)) == NULL) {
10297         goto fail;
10298     }
10299     Py_CLEAR(obj1);
10300     Py_CLEAR(obj2);
10301     FMT_OBJ_AND_APPEND(lines, _("Validity"), obj, level, fail);
10302     Py_CLEAR(obj);
10303 
10304     return lines;
10305  fail:
10306     Py_XDECREF(obj);
10307     Py_XDECREF(obj1);
10308     Py_XDECREF(obj2);
10309     return NULL;
10310 }
10311 
10312 static PyObject *
Certificate_format_lines(Certificate * self,PyObject * args,PyObject * kwds)10313 Certificate_format_lines(Certificate *self, PyObject *args, PyObject *kwds)
10314 {
10315     static char *kwlist[] = {"level", NULL};
10316     int level = 0;
10317     Py_ssize_t len, i;
10318     PyObject *lines = NULL;
10319     PyObject *obj = NULL;
10320     PyObject *obj1 = NULL;
10321     PyObject *obj2 = NULL;
10322     PyObject *obj3 = NULL;
10323     PyObject *obj_line_fmt_tuples = NULL;
10324     PyObject *obj_lines = NULL;
10325     PyObject *ssl_trust_lines = NULL, *email_trust_lines = NULL, *signing_trust_lines = NULL;
10326     PyObject *tmp_args = NULL;
10327     PyObject *extensions = NULL;
10328 
10329     TraceMethodEnter(self);
10330 
10331     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:format_lines", kwlist, &level))
10332         return NULL;
10333 
10334     if ((lines = PyList_New(0)) == NULL) {
10335         goto fail;
10336     }
10337 
10338     FMT_LABEL_AND_APPEND(lines, _("Data"), level, fail);
10339 
10340     if ((obj = Certificate_get_version(self, NULL)) == NULL) {
10341         goto fail;
10342     }
10343     if ((obj1 = PyLong_FromLong(1)) == NULL) {
10344         goto fail;
10345     }
10346     if ((obj2 = PyNumber_Add(obj, obj1)) == NULL) {
10347         goto fail;
10348     }
10349     if ((obj3 = obj_sprintf("%d (%#x)", obj2, obj)) == NULL) {
10350         goto fail;
10351     }
10352     FMT_OBJ_AND_APPEND(lines, _("Version"), obj3, level+2, fail);
10353     Py_CLEAR(obj);
10354     Py_CLEAR(obj1);
10355     Py_CLEAR(obj2);
10356     Py_CLEAR(obj3);
10357 
10358     if ((obj = Certificate_get_serial_number(self, NULL)) == NULL) {
10359         goto fail;
10360     }
10361     if ((obj1 = obj_sprintf("%d (%#x)", obj, obj)) == NULL) {
10362         goto fail;
10363     }
10364     FMT_OBJ_AND_APPEND(lines, _("Serial Number"), obj1, level+2, fail);
10365     Py_CLEAR(obj);
10366     Py_CLEAR(obj1);
10367 
10368     if ((obj = Certificate_get_signature_algorithm(self, NULL)) == NULL) {
10369         goto fail;
10370     }
10371     FMT_LABEL_AND_APPEND(lines, _("Signature Algorithm"), level+2, fail);
10372     CALL_FORMAT_LINES_AND_APPEND(lines, obj, level+3, fail);
10373     Py_CLEAR(obj);
10374 
10375     if ((obj = Certificate_get_issuer(self, NULL)) == NULL) {
10376         goto fail;
10377     }
10378     FMT_OBJ_AND_APPEND(lines, _("Issuer"), obj, level+2, fail);
10379     Py_CLEAR(obj);
10380 
10381     FMT_LABEL_AND_APPEND(lines, _("Validity"), level+2, fail);
10382 
10383     if ((obj = Certificate_get_valid_not_before_str(self, NULL)) == NULL) {
10384         goto fail;
10385     }
10386     FMT_OBJ_AND_APPEND(lines, _("Not Before"), obj, level+3, fail);
10387     Py_CLEAR(obj);
10388 
10389     if ((obj = Certificate_get_valid_not_after_str(self, NULL)) == NULL) {
10390         goto fail;
10391     }
10392     FMT_OBJ_AND_APPEND(lines, _("Not After"), obj, level+3, fail);
10393     Py_CLEAR(obj);
10394 
10395     if ((obj = Certificate_get_subject(self, NULL)) == NULL) {
10396         goto fail;
10397     }
10398     FMT_OBJ_AND_APPEND(lines, _("Subject"), obj, level+2, fail);
10399     Py_CLEAR(obj);
10400 
10401     FMT_LABEL_AND_APPEND(lines, _("Subject Public Key Info"), level+2, fail);
10402 
10403     if ((obj = Certificate_get_subject_public_key_info(self, NULL)) == NULL) {
10404         goto fail;
10405     }
10406 
10407     CALL_FORMAT_LINES_AND_APPEND(lines, obj, level+3, fail);
10408     Py_CLEAR(obj);
10409 
10410     if ((extensions = Certificate_get_extensions(self, NULL)) == NULL) {
10411         goto fail;
10412     }
10413 
10414     len = PyTuple_Size(extensions);
10415     if ((obj = PyUnicode_FromFormat("Signed Extensions: (%zd total)", len)) == NULL) {
10416         goto fail;
10417     }
10418     FMT_OBJ_AND_APPEND(lines, NULL, obj, level+1, fail);
10419     Py_CLEAR(obj);
10420 
10421     for (i = 0; i < len; i++) {
10422         obj = PyTuple_GetItem(extensions, i);
10423         CALL_FORMAT_LINES_AND_APPEND(lines, obj, level+2, fail);
10424         FMT_LABEL_AND_APPEND(lines, NULL, 0, fail);
10425     }
10426     Py_CLEAR(extensions);
10427 
10428     if ((ssl_trust_lines = Certificate_get_ssl_trust_str(self, NULL)) == NULL) {
10429         goto fail;
10430     }
10431     if ((email_trust_lines = Certificate_get_email_trust_str(self, NULL)) == NULL) {
10432         goto fail;
10433     }
10434     if ((signing_trust_lines = Certificate_get_signing_trust_str(self, NULL)) == NULL) {
10435         goto fail;
10436     }
10437 
10438     if ((ssl_trust_lines != Py_None) || (email_trust_lines != Py_None) || (signing_trust_lines != Py_None)) {
10439         FMT_LABEL_AND_APPEND(lines, _("Certificate Trust Flags"), level+2, fail);
10440 
10441         if (PyList_Check(ssl_trust_lines)) {
10442             FMT_LABEL_AND_APPEND(lines, _("SSL Flags"), level+3, fail);
10443             APPEND_LINES_AND_CLEAR(lines, ssl_trust_lines, level+4, fail);
10444         }
10445 
10446         if (PyList_Check(email_trust_lines)) {
10447             FMT_LABEL_AND_APPEND(lines, _("Email Flags"), level+3, fail);
10448             APPEND_LINES_AND_CLEAR(lines, email_trust_lines, level+4, fail);
10449         }
10450 
10451         if (PyList_Check(signing_trust_lines)) {
10452             FMT_LABEL_AND_APPEND(lines, _("Object Signing Flags"), level+3, fail);
10453             APPEND_LINES_AND_CLEAR(lines, signing_trust_lines, level+4, fail);
10454         }
10455 
10456     }
10457     Py_CLEAR(ssl_trust_lines);
10458     Py_CLEAR(email_trust_lines);
10459     Py_CLEAR(signing_trust_lines);
10460 
10461     FMT_LABEL_AND_APPEND(lines, _("Signature"), level+1, fail);
10462 
10463     if ((obj = Certificate_get_signed_data(self, NULL)) == NULL) {
10464         goto fail;
10465     }
10466 
10467     CALL_FORMAT_LINES_AND_APPEND(lines, obj, level+2, fail);
10468     Py_CLEAR(obj);
10469 
10470     return lines;
10471  fail:
10472     Py_XDECREF(obj);
10473     Py_XDECREF(obj1);
10474     Py_XDECREF(obj2);
10475     Py_XDECREF(obj3);
10476     Py_XDECREF(lines);
10477     Py_XDECREF(obj_line_fmt_tuples);
10478     Py_XDECREF(obj_lines);
10479     Py_XDECREF(tmp_args);
10480     Py_XDECREF(ssl_trust_lines);
10481     Py_XDECREF(email_trust_lines);
10482     Py_XDECREF(signing_trust_lines);
10483     Py_XDECREF(extensions);
10484     return NULL;
10485 }
10486 
10487 static PyObject *
Certificate_format(Certificate * self,PyObject * args,PyObject * kwds)10488 Certificate_format(Certificate *self, PyObject *args, PyObject *kwds)
10489 {
10490     TraceMethodEnter(self);
10491 
10492     return format_from_lines((format_lines_func)Certificate_format_lines, (PyObject *)self, args, kwds);
10493 }
10494 
10495 static PyObject *
Certificate_str(Certificate * self)10496 Certificate_str(Certificate *self)
10497 {
10498     PyObject *py_formatted_result = NULL;
10499 
10500     py_formatted_result = Certificate_format(self, empty_tuple, NULL);
10501     return py_formatted_result;
10502 
10503 }
10504 
10505 static PyMethodDef Certificate_methods[] = {
10506     {"trust_flags",            (PyCFunction)Certificate_trust_flags,            METH_VARARGS | METH_CLASS,  Certificate_trust_flags_doc},
10507     {"set_trust_attributes",   (PyCFunction)Certificate_set_trust_attributes,   METH_VARARGS,               Certificate_set_trust_attributes_doc},
10508     {"find_kea_type",          (PyCFunction)Certificate_find_kea_type,          METH_NOARGS,                Certificate_find_kea_type_doc},
10509     {"make_ca_nickname",       (PyCFunction)Certificate_make_ca_nickname,       METH_NOARGS,                Certificate_make_ca_nickname_doc},
10510     {"has_signer_in_ca_names", (PyCFunction)Certificate_has_signer_in_ca_names, METH_VARARGS,               Certificate_has_signer_in_ca_names_doc},
10511     {"verify_hostname",        (PyCFunction)Certificate_verify_hostname,        METH_VARARGS,               Certificate_verify_hostname_doc},
10512     {"check_valid_times",      (PyCFunction)Certificate_check_valid_times,      METH_VARARGS|METH_KEYWORDS, Certificate_check_valid_times_doc},
10513     {"is_ca_cert",             (PyCFunction)Certificate_is_ca_cert,             METH_VARARGS|METH_KEYWORDS, Certificate_is_ca_cert_doc},
10514     {"verify_now",             (PyCFunction)Certificate_verify_now,             METH_VARARGS,               Certificate_verify_now_doc},
10515     {"verify",                 (PyCFunction)Certificate_verify,                 METH_VARARGS,               Certificate_verify_doc},
10516     {"verify_with_log",        (PyCFunction)Certificate_verify_with_log,        METH_VARARGS,               Certificate_verify_with_log_doc},
10517     {"check_ocsp_status",      (PyCFunction)Certificate_check_ocsp_status,      METH_VARARGS,               Certificate_check_ocsp_status_doc},
10518     {"get_cert_chain",         (PyCFunction)Certificate_get_cert_chain,         METH_VARARGS|METH_KEYWORDS, Certificate_get_cert_chain_doc},
10519     {"get_extension",          (PyCFunction)Certificate_get_extension,          METH_VARARGS|METH_KEYWORDS, Certificate_get_extension_doc},
10520     {"format_lines",           (PyCFunction)Certificate_format_lines,           METH_VARARGS|METH_KEYWORDS, generic_format_lines_doc},
10521     {"format",                 (PyCFunction)Certificate_format,                 METH_VARARGS|METH_KEYWORDS, generic_format_doc},
10522     {NULL, NULL}  /* Sentinel */
10523 };
10524 
10525 /* =========================== Class Construction =========================== */
10526 
10527 static PyObject *
Certificate_new(PyTypeObject * type,PyObject * args,PyObject * kwds)10528 Certificate_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
10529 {
10530     Certificate *self;
10531 
10532     TraceObjNewEnter(type);
10533 
10534     if ((self = (Certificate *)type->tp_alloc(type, 0)) == NULL) {
10535         return NULL;
10536     }
10537     self->cert = NULL;
10538 
10539     TraceObjNewLeave(self);
10540     return (PyObject *)self;
10541 }
10542 
10543 static void
Certificate_dealloc(Certificate * self)10544 Certificate_dealloc(Certificate* self)
10545 {
10546     TraceMethodEnter(self);
10547 
10548 #ifdef DEBUG
10549     print_cert(self->cert, "%s before CERT_DestroyCertificate" ,__FUNCTION__);
10550 #endif
10551 
10552     if (self->cert) {
10553         CERT_DestroyCertificate(self->cert);
10554     }
10555 
10556     Py_TYPE(self)->tp_free((PyObject*)self);
10557 }
10558 
10559 PyDoc_STRVAR(Certificate_doc,
10560 "Certificate(data, certdb=get_default_certdb(), perm=False, nickname=None)\n\
10561 \n\
10562 :Parameters:\n\
10563     data : SecItem or str or any buffer compatible object\n\
10564         Data to initialize the certificate from, must be in DER format\n\
10565     certdb : CertDB object or None\n\
10566         CertDB certificate database object, if None then the default\n\
10567         certdb will be supplied by calling `nss.get_default_certdb()`.\n\
10568     perm : bool\n\
10569         True if certificate should be permantely stored in the certdb.\n\
10570     nickname : string\n\
10571         certificate nickname.\n\
10572 \n\
10573 An X509 Certificate object.\n\
10574 \n\
10575 The Certificate is initialized from the supplied DER data. The\n\
10576 Certificate is added to the NSS temporary database. If perm is True\n\
10577 then the Certificate is also permanently written into certdb.\n\
10578 ");
10579 
10580 static int
Certificate_init(Certificate * self,PyObject * args,PyObject * kwds)10581 Certificate_init(Certificate *self, PyObject *args, PyObject *kwds)
10582 {
10583     static char *kwlist[] = {"data", "certdb", "perm", "nickname", NULL};
10584     SECItem_param *data_param = NULL;
10585     CertDB *py_certdb = NULL;
10586     PyObject *py_perm = NULL;
10587     PyObject *py_nickname = NULL;
10588 
10589     CERTCertDBHandle *certdb_handle = NULL;
10590     SECItem *der_certs = NULL;
10591     CERTCertificate **certs = NULL;
10592     PRBool perm = PR_FALSE;
10593     unsigned int n_certs = 1;
10594     int result = 0;
10595 
10596     TraceMethodEnter(self);
10597 
10598     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&|O!O!O&:Certificate", kwlist,
10599                                      SECItemConvert, &data_param,
10600                                      &CertDBType, &py_certdb,
10601                                      &PyBool_Type, &py_perm,
10602                                      UTF8OrNoneConvert, &py_nickname))
10603         return -1;
10604 
10605     if (py_certdb) {
10606         certdb_handle = py_certdb->handle;
10607     } else {
10608         certdb_handle = CERT_GetDefaultCertDB();
10609     }
10610 
10611     if (py_perm) {
10612         perm = PyBoolAsPRBool(py_perm);
10613     }
10614 
10615     der_certs = &data_param->item;
10616 
10617     Py_BEGIN_ALLOW_THREADS
10618     if (CERT_ImportCerts(certdb_handle, certUsageUserCertImport,
10619                          n_certs, &der_certs, &certs,
10620                          perm, PR_FALSE,
10621                          py_nickname ? PyBytes_AsString(py_nickname) : NULL) != SECSuccess) {
10622         Py_BLOCK_THREADS
10623         set_nspr_error(NULL);
10624         result = -1;
10625         goto exit;
10626     }
10627     Py_END_ALLOW_THREADS
10628 
10629 #ifdef DEBUG
10630     print_cert(certs[0], "%s after CERT_ImportCerts certificate perm=%s" ,__FUNCTION__, perm ? "True":"False");
10631 #endif
10632 
10633     if ((self->cert = CERT_DupCertificate(certs[0])) == NULL) {
10634         set_nspr_error(NULL);
10635         result = -1;
10636         goto exit;
10637     }
10638 
10639  exit:
10640     SECItem_param_release(data_param);
10641     Py_XDECREF(py_nickname);
10642     if (certs != NULL) {
10643 	CERT_DestroyCertArray(certs, n_certs);
10644     }
10645 
10646     return result;
10647 }
10648 
10649 
10650 static PyTypeObject CertificateType = {
10651     PyVarObject_HEAD_INIT(NULL, 0)
10652     "nss.nss.Certificate",			/* tp_name */
10653     sizeof(Certificate),			/* tp_basicsize */
10654     0,						/* tp_itemsize */
10655     (destructor)Certificate_dealloc,		/* tp_dealloc */
10656     0,						/* tp_print */
10657     0,						/* tp_getattr */
10658     0,						/* tp_setattr */
10659     0,						/* tp_compare */
10660     0,						/* tp_repr */
10661     0,						/* tp_as_number */
10662     0,						/* tp_as_sequence */
10663     0,						/* tp_as_mapping */
10664     0,						/* tp_hash */
10665     0,						/* tp_call */
10666     (reprfunc)Certificate_str,			/* tp_str */
10667     0,						/* tp_getattro */
10668     0,						/* tp_setattro */
10669     0,						/* tp_as_buffer */
10670     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,	/* tp_flags */
10671     Certificate_doc,				/* tp_doc */
10672     0,						/* tp_traverse */
10673     0,						/* tp_clear */
10674     0,						/* tp_richcompare */
10675     0,						/* tp_weaklistoffset */
10676     0,						/* tp_iter */
10677     0,						/* tp_iternext */
10678     Certificate_methods,			/* tp_methods */
10679     Certificate_members,			/* tp_members */
10680     Certificate_getseters,			/* tp_getset */
10681     0,						/* tp_base */
10682     0,						/* tp_dict */
10683     0,						/* tp_descr_get */
10684     0,						/* tp_descr_set */
10685     0,						/* tp_dictoffset */
10686     (initproc)Certificate_init,			/* tp_init */
10687     0,						/* tp_alloc */
10688     Certificate_new,				/* tp_new */
10689 };
10690 
10691 static PyObject *
Certificate_new_from_CERTCertificate(CERTCertificate * cert,bool add_reference)10692 Certificate_new_from_CERTCertificate(CERTCertificate *cert, bool add_reference)
10693 {
10694     Certificate *self = NULL;
10695 
10696     TraceObjNewEnter(NULL);
10697 
10698 #ifdef DEBUG
10699     print_cert(cert, "%s certificate" ,__FUNCTION__);
10700 #endif
10701 
10702     if ((self = (Certificate *) CertificateType.tp_new(&CertificateType, NULL, NULL)) == NULL) {
10703         return NULL;
10704     }
10705 
10706     if (add_reference) {
10707         if ((self->cert = CERT_DupCertificate(cert)) == NULL) {
10708             return set_nspr_error(NULL);
10709         }
10710     } else {
10711         self->cert = cert;
10712     }
10713 
10714     TraceObjNewLeave(self);
10715     return (PyObject *) self;
10716 }
10717 
10718 static PyObject *
Certificate_new_from_signed_der_secitem(SECItem * der)10719 Certificate_new_from_signed_der_secitem(SECItem *der)
10720 {
10721 #if 0
10722     PyObject *py_der = NULL;
10723     PyObject *py_cert = NULL;
10724     PRArenaPool *arena = NULL;
10725     CERTSignedData *sd = NULL;
10726 
10727     if ((arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE)) == NULL) {
10728         set_nspr_error(NULL);
10729         goto exit;
10730     }
10731 
10732     if ((sd = PORT_ArenaZNew(arena, CERTSignedData)) == NULL) {
10733         set_nspr_error(NULL);
10734         goto exit;
10735     }
10736 
10737     if (SEC_ASN1DecodeItem(arena, sd, SEC_ASN1_GET(CERT_SignedDataTemplate), der) != SECSuccess) {
10738         set_nspr_error("bad signed certificate DER data");
10739         goto exit;
10740     }
10741 
10742     if ((py_der = SecItem_new_from_SECItem(&sd->data, SECITEM_certificate)) == NULL) {
10743         goto exit;
10744     }
10745 
10746     if ((py_cert = PyObject_CallFunction((PyObject *)&CertificateType, "O", py_der)) == NULL) {
10747         goto exit;
10748     }
10749 
10750  exit:
10751     Py_XDECREF(py_der);
10752     PORT_FreeArena(arena, PR_FALSE);
10753     return py_cert;
10754 #else
10755     PyObject *py_der = NULL;
10756     PyObject *py_cert = NULL;
10757 
10758     if ((py_der = SecItem_new_from_SECItem(der, SECITEM_certificate)) == NULL) {
10759         goto exit;
10760     }
10761 
10762     if ((py_cert = PyObject_CallFunction((PyObject *)&CertificateType, "O", py_der)) == NULL) {
10763         goto exit;
10764     }
10765 
10766  exit:
10767     Py_XDECREF(py_der);
10768     return py_cert;
10769 #endif
10770 }
10771 
10772 /* ========================================================================== */
10773 /* ============================= PrivateKey Class =========================== */
10774 /* ========================================================================== */
10775 
10776 /* ============================ Attribute Access ============================ */
10777 
10778 static
10779 PyGetSetDef PrivateKey_getseters[] = {
10780     {NULL}  /* Sentinel */
10781 };
10782 
10783 static PyMemberDef PrivateKey_members[] = {
10784     {NULL}  /* Sentinel */
10785 };
10786 
10787 /* ============================== Class Methods ============================= */
10788 
10789 
10790 static PyMethodDef PrivateKey_methods[] = {
10791     {NULL, NULL}  /* Sentinel */
10792 };
10793 
10794 /* =========================== Class Construction =========================== */
10795 
10796 static PyObject *
PrivateKey_new(PyTypeObject * type,PyObject * args,PyObject * kwds)10797 PrivateKey_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
10798 {
10799     PrivateKey *self;
10800 
10801     TraceObjNewEnter(type);
10802 
10803     if ((self = (PrivateKey *)type->tp_alloc(type, 0)) == NULL) {
10804         return NULL;
10805     }
10806     self->private_key = NULL;
10807 
10808     TraceObjNewLeave(self);
10809     return (PyObject *)self;
10810 }
10811 
10812 static void
PrivateKey_dealloc(PrivateKey * self)10813 PrivateKey_dealloc(PrivateKey* self)
10814 {
10815     TraceMethodEnter(self);
10816 
10817     if (self->private_key)
10818         SECKEY_DestroyPrivateKey(self->private_key);
10819 
10820     Py_TYPE(self)->tp_free((PyObject*)self);
10821 }
10822 
10823 PyDoc_STRVAR(PrivateKey_doc,
10824 "An object representing a Private Key");
10825 
10826 static int
PrivateKey_init(PrivateKey * self,PyObject * args,PyObject * kwds)10827 PrivateKey_init(PrivateKey *self, PyObject *args, PyObject *kwds)
10828 {
10829     TraceMethodEnter(self);
10830     return 0;
10831 }
10832 
10833 static PyTypeObject PrivateKeyType = {
10834     PyVarObject_HEAD_INIT(NULL, 0)
10835     "nss.nss.PrivateKey",			/* tp_name */
10836     sizeof(PrivateKey),				/* tp_basicsize */
10837     0,						/* tp_itemsize */
10838     (destructor)PrivateKey_dealloc,		/* tp_dealloc */
10839     0,						/* tp_print */
10840     0,						/* tp_getattr */
10841     0,						/* tp_setattr */
10842     0,						/* tp_compare */
10843     0,						/* tp_repr */
10844     0,						/* tp_as_number */
10845     0,						/* tp_as_sequence */
10846     0,						/* tp_as_mapping */
10847     0,						/* tp_hash */
10848     0,						/* tp_call */
10849     0,						/* tp_str */
10850     0,						/* tp_getattro */
10851     0,						/* tp_setattro */
10852     0,						/* tp_as_buffer */
10853     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,	/* tp_flags */
10854     PrivateKey_doc,				/* tp_doc */
10855     0,						/* tp_traverse */
10856     0,						/* tp_clear */
10857     0,						/* tp_richcompare */
10858     0,						/* tp_weaklistoffset */
10859     0,						/* tp_iter */
10860     0,						/* tp_iternext */
10861     PrivateKey_methods,				/* tp_methods */
10862     PrivateKey_members,				/* tp_members */
10863     PrivateKey_getseters,			/* tp_getset */
10864     0,						/* tp_base */
10865     0,						/* tp_dict */
10866     0,						/* tp_descr_get */
10867     0,						/* tp_descr_set */
10868     0,						/* tp_dictoffset */
10869     (initproc)PrivateKey_init,			/* tp_init */
10870     0,						/* tp_alloc */
10871     PrivateKey_new,				/* tp_new */
10872 };
10873 
10874 static PyObject *
PrivateKey_new_from_SECKEYPrivateKey(SECKEYPrivateKey * private_key)10875 PrivateKey_new_from_SECKEYPrivateKey(SECKEYPrivateKey *private_key)
10876 {
10877     PrivateKey *self = NULL;
10878 
10879     TraceObjNewEnter(NULL);
10880     if ((self = (PrivateKey *) PrivateKeyType.tp_new(&PrivateKeyType, NULL, NULL)) == NULL) {
10881         return NULL;
10882     }
10883 
10884     self->private_key = private_key;
10885 
10886     TraceObjNewLeave(self);
10887     return (PyObject *) self;
10888 }
10889 
10890 
10891 /* ========================================================================== */
10892 /* ============================== SignedCRL Class =========================== */
10893 /* ========================================================================== */
10894 
10895 /* ============================ Attribute Access ============================ */
10896 
10897 static
10898 PyGetSetDef SignedCRL_getseters[] = {
10899     {NULL}  /* Sentinel */
10900 };
10901 
10902 static PyMemberDef SignedCRL_members[] = {
10903     {NULL}  /* Sentinel */
10904 };
10905 
10906 /* ============================== Class Methods ============================= */
10907 
10908 PyDoc_STRVAR(SignedCRL_delete_permanently_doc,
10909 "delete_permanently()\n\
10910 \n\
10911 Permanently remove the CRL from the database.\n\
10912 ");
10913 
10914 static PyObject *
SignedCRL_delete_permanently(SignedCRL * self,PyObject * args)10915 SignedCRL_delete_permanently(SignedCRL *self, PyObject *args)
10916 {
10917     TraceMethodEnter(self);
10918 
10919     if (SEC_DeletePermCRL(self->signed_crl) != SECSuccess) {
10920         return set_nspr_error(NULL);
10921     }
10922 
10923     Py_RETURN_NONE;
10924 }
10925 
10926 static PyMethodDef SignedCRL_methods[] = {
10927     {"delete_permanently", (PyCFunction)SignedCRL_delete_permanently, METH_NOARGS,  SignedCRL_delete_permanently_doc},
10928     {NULL, NULL}  /* Sentinel */
10929 };
10930 
10931 /* =========================== Class Construction =========================== */
10932 
10933 static PyObject *
SignedCRL_new(PyTypeObject * type,PyObject * args,PyObject * kwds)10934 SignedCRL_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
10935 {
10936     SignedCRL *self;
10937 
10938     TraceObjNewEnter(type);
10939 
10940     if ((self = (SignedCRL *)type->tp_alloc(type, 0)) == NULL) {
10941         return NULL;
10942     }
10943     self->signed_crl = NULL;
10944 
10945     TraceObjNewLeave(self);
10946     return (PyObject *)self;
10947 }
10948 
10949 static void
SignedCRL_dealloc(SignedCRL * self)10950 SignedCRL_dealloc(SignedCRL* self)
10951 {
10952     TraceMethodEnter(self);
10953 
10954     if (self->signed_crl)
10955         SEC_DestroyCrl(self->signed_crl);
10956 
10957     Py_TYPE(self)->tp_free((PyObject*)self);
10958 }
10959 
10960 PyDoc_STRVAR(SignedCRL_doc,
10961 "An object representing a signed certificate revocation list");
10962 
10963 static int
SignedCRL_init(SignedCRL * self,PyObject * args,PyObject * kwds)10964 SignedCRL_init(SignedCRL *self, PyObject *args, PyObject *kwds)
10965 {
10966     TraceMethodEnter(self);
10967     return 0;
10968 }
10969 
10970 static PyTypeObject SignedCRLType = {
10971     PyVarObject_HEAD_INIT(NULL, 0)
10972     "nss.nss.SignedCRL",			/* tp_name */
10973     sizeof(SignedCRL),				/* tp_basicsize */
10974     0,						/* tp_itemsize */
10975     (destructor)SignedCRL_dealloc,		/* tp_dealloc */
10976     0,						/* tp_print */
10977     0,						/* tp_getattr */
10978     0,						/* tp_setattr */
10979     0,						/* tp_compare */
10980     0,						/* tp_repr */
10981     0,						/* tp_as_number */
10982     0,						/* tp_as_sequence */
10983     0,						/* tp_as_mapping */
10984     0,						/* tp_hash */
10985     0,						/* tp_call */
10986     0,						/* tp_str */
10987     0,						/* tp_getattro */
10988     0,						/* tp_setattro */
10989     0,						/* tp_as_buffer */
10990     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,	/* tp_flags */
10991     SignedCRL_doc,				/* tp_doc */
10992     0,						/* tp_traverse */
10993     0,						/* tp_clear */
10994     0,						/* tp_richcompare */
10995     0,						/* tp_weaklistoffset */
10996     0,						/* tp_iter */
10997     0,						/* tp_iternext */
10998     SignedCRL_methods,				/* tp_methods */
10999     SignedCRL_members,				/* tp_members */
11000     SignedCRL_getseters,			/* tp_getset */
11001     0,						/* tp_base */
11002     0,						/* tp_dict */
11003     0,						/* tp_descr_get */
11004     0,						/* tp_descr_set */
11005     0,						/* tp_dictoffset */
11006     (initproc)SignedCRL_init,			/* tp_init */
11007     0,						/* tp_alloc */
11008     SignedCRL_new,				/* tp_new */
11009 };
11010 
11011 static PyObject *
SignedCRL_new_from_CERTSignedCRL(CERTSignedCrl * signed_crl)11012 SignedCRL_new_from_CERTSignedCRL(CERTSignedCrl *signed_crl)
11013 {
11014     SignedCRL *self = NULL;
11015 
11016     TraceObjNewEnter(NULL);
11017     if ((self = (SignedCRL *) SignedCRLType.tp_new(&SignedCRLType, NULL, NULL)) == NULL) {
11018         return NULL;
11019     }
11020 
11021     self->signed_crl = signed_crl;
11022 
11023     TraceObjNewLeave(self);
11024     return (PyObject *) self;
11025 }
11026 
11027 /* ========================================================================== */
11028 /* =============================== AVA Class ================================ */
11029 /* ========================================================================== */
11030 
11031 /*
11032  * Note: CERT_CopyAVA, CERT_GetAVATag, CERT_CompareAVA, CERT_CreateAVA,
11033  * and CERT_DecodeAVAValue are defined in cert.h
11034  *
11035  * But only CERT_GetAVATag, CERT_CreateAVA, CERT_DecodeAVAValue are exported
11036  * by nss.def
11037  *
11038  * That means CERT_CopyAVA and CERT_CompareAVA are defined as public but aren't.
11039  */
11040 
11041 /* ============================ Attribute Access ============================ */
11042 
11043 static PyObject *
AVA_get_oid(AVA * self,void * closure)11044 AVA_get_oid(AVA *self, void *closure)
11045 {
11046     TraceMethodEnter(self);
11047 
11048     return SecItem_new_from_SECItem(&self->ava->type, SECITEM_oid);
11049 }
11050 
11051 static PyObject *
AVA_get_oid_tag(AVA * self,void * closure)11052 AVA_get_oid_tag(AVA *self, void *closure)
11053 {
11054     TraceMethodEnter(self);
11055 
11056     return PyLong_FromLong(CERT_GetAVATag(self->ava));
11057 }
11058 
11059 static PyObject *
AVA_get_value(AVA * self,void * closure)11060 AVA_get_value(AVA *self, void *closure)
11061 {
11062     TraceMethodEnter(self);
11063 
11064     return SecItem_new_from_SECItem(&self->ava->value, SECITEM_utf8_string);
11065 }
11066 
11067 static PyObject *
AVA_get_value_str(AVA * self,void * closure)11068 AVA_get_value_str(AVA *self, void *closure)
11069 {
11070     TraceMethodEnter(self);
11071 
11072     return AVA_repr(self);
11073 }
11074 
11075 static
11076 PyGetSetDef AVA_getseters[] = {
11077     {"oid",       (getter)AVA_get_oid, (setter)NULL,
11078      "The OID (e.g. type) of the AVA as a SecItem", NULL},
11079     {"oid_tag",   (getter)AVA_get_oid_tag, (setter)NULL,
11080      "The OID tag enumerated constant (i.e. SEC_OID_AVA_*) of the AVA's type", NULL},
11081     {"value",     (getter)AVA_get_value, (setter)NULL,
11082      "The value of the AVA as a SecItem", NULL},
11083     {"value_str", (getter)AVA_get_value_str, (setter)NULL,
11084      "The value of the AVA as a UTF-8 encoded string", NULL},
11085     {NULL}  /* Sentinel */
11086 };
11087 
11088 static PyMemberDef AVA_members[] = {
11089     {NULL}  /* Sentinel */
11090 };
11091 
11092 /* ============================== Class Methods ============================= */
11093 
11094 
11095 /*
11096  * Compares two CERTAVA's, returns -1 if a < b, 0 if a == b, 1 if a > b
11097  * If error, returns -2
11098  */
11099 static int
CERTAVA_compare(CERTAVA * a,CERTAVA * b)11100 CERTAVA_compare(CERTAVA *a, CERTAVA *b)
11101 {
11102     SECComparison sec_cmp_result;
11103     int int_cmp_result;
11104     PyObject *a_val_str, *b_val_str;
11105     PyObject *a_val_str_lower, *b_val_str_lower;
11106 
11107     if (a == NULL && b == NULL) return 0;
11108     if (a == NULL && b != NULL) return -1;
11109     if (a != NULL && b == NULL) return 1;
11110 
11111     if ((sec_cmp_result = SECITEM_CompareItem(&a->type, &b->type)) != SECEqual) {
11112 #if 0 /* FIXME when https://bugzilla.redhat.com/show_bug.cgi?id=804802 is fixed */
11113         return sec_cmp_result == SECLessThan ? -1 : 1;
11114 #else
11115         return sec_cmp_result < 0 ? SECLessThan : SECGreaterThan;
11116 #endif
11117     }
11118 
11119     /* Attribute types matched, are values equal? */
11120     if ((sec_cmp_result = SECITEM_CompareItem(&a->value,
11121                                               &b->value)) == SECEqual) {
11122         return 0;
11123     }
11124 
11125     /* Values are not equal, compare as case insenstive strings */
11126     a_val_str = CERTAVA_value_to_pystr(a);
11127     b_val_str = CERTAVA_value_to_pystr(b);
11128     if (a_val_str == NULL || b_val_str == NULL) {
11129         Py_XDECREF(a_val_str);
11130         Py_XDECREF(b_val_str);
11131         PyErr_SetString(PyExc_ValueError, "Failed to convert AVA value to string");
11132         return -2;
11133     }
11134 
11135     a_val_str_lower = PyUnicode_Lower(a_val_str);
11136     b_val_str_lower = PyUnicode_Lower(b_val_str);
11137     if (a_val_str_lower == NULL || b_val_str_lower == NULL) {
11138         Py_XDECREF(a_val_str);
11139         Py_XDECREF(b_val_str);
11140         Py_XDECREF(a_val_str_lower);
11141         Py_XDECREF(b_val_str_lower);
11142         PyErr_SetString(PyExc_ValueError, "Failed to lower case AVA value");
11143         return -2;
11144     }
11145 
11146     int_cmp_result = PyUnicode_Compare(a_val_str_lower, b_val_str_lower);
11147 
11148     Py_DECREF(a_val_str);
11149     Py_DECREF(b_val_str);
11150     Py_DECREF(a_val_str_lower);
11151     Py_DECREF(b_val_str_lower);
11152     return (int_cmp_result == 0) ? 0 : ((int_cmp_result < 0) ? -1 : 1);
11153 }
11154 
11155 static PyObject *
AVA_richcompare(AVA * self,AVA * other,int op)11156 AVA_richcompare(AVA *self, AVA *other, int op)
11157 {
11158     int cmp_result;
11159 
11160     if (!PyAVA_Check(other)) {
11161         PyErr_SetString(PyExc_TypeError, "Bad type, must be AVA");
11162         return NULL;
11163     }
11164 
11165     cmp_result = CERTAVA_compare(self->ava, other->ava);
11166     if (cmp_result == -2) {
11167         return NULL;
11168     }
11169     RETURN_COMPARE_RESULT(op, cmp_result)
11170 }
11171 
11172 static PyMethodDef AVA_methods[] = {
11173     {NULL, NULL}  /* Sentinel */
11174 };
11175 
11176 /* =========================== Class Construction =========================== */
11177 
11178 static PyObject *
AVA_new(PyTypeObject * type,PyObject * args,PyObject * kwds)11179 AVA_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
11180 {
11181     AVA *self;
11182 
11183     TraceObjNewEnter(type);
11184 
11185     if ((self = (AVA *)type->tp_alloc(type, 0)) == NULL) {
11186         return NULL;
11187     }
11188 
11189     if ((self->arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE)) == NULL) {
11190         type->tp_free(self);
11191         return set_nspr_error(NULL);
11192     }
11193 
11194     self->ava = NULL;
11195 
11196     TraceObjNewLeave(self);
11197     return (PyObject *)self;
11198 }
11199 
11200 static void
AVA_dealloc(AVA * self)11201 AVA_dealloc(AVA* self)
11202 {
11203     TraceMethodEnter(self);
11204 
11205     if (self->arena) {
11206         PORT_FreeArena(self->arena, PR_FALSE);
11207     }
11208 
11209     Py_TYPE(self)->tp_free((PyObject*)self);
11210 }
11211 
11212 PyDoc_STRVAR(AVA_doc,
11213 "An object representing an AVA (attribute value assertion).\n\
11214 \n\
11215 AVA(type, value)\n\
11216 \n\
11217 :Parameters:\n\
11218      type : may be one of integer, string, SecItem\n\
11219          What kind of attribute is being created. May be\n\
11220          one of:\n\
11221 \n\
11222          * integer: A SEC OID enumeration constant (i.e. SEC_OID_*)\n\
11223            for example SEC_OID_AVA_COMMON_NAME.\n\
11224          * string: A string either as the ava name, for example 'cn'\n\
11225            or as the dotted decimal representation, for example\n\
11226            'OID.2.5.4.3'. Case is not significant for either form.\n\
11227          * SecItem: A SecItem object encapsulating the OID in \n\
11228            DER format.\n\
11229      value : string\n\
11230          The value of the AVA, must be a string.\n\
11231 \n\
11232 RDN's (Relative Distinguished Name) are composed from AVA's.\n\
11233 An `RDN` is a sequence of AVA's.\n\
11234 \n\
11235 An example of an AVA is \"CN=www.redhat.com\" where CN is the X500\n\
11236 directory abbrevation for \"Common Name\".\n\
11237 \n\
11238 An AVA is composed of two items:\n\
11239 \n\
11240 type\n\
11241     Specifies the attribute (e.g. CN). AVA types are specified by\n\
11242     predefined OID's (Object Identifiers). For example the OID of CN\n\
11243     is 2.5.4.3 ({joint-iso-itu-t(2) ds(5) attributeType(4) commonName(3)})\n\
11244     OID's in NSS are encapsulated in a SecItem as a DER encoded OID.\n\
11245     Because DER encoded OID's are less than ideal mechanisms by which\n\
11246     to specify an item NSS has mapped each OID to a integral enumerated\n\
11247     constant called an OID tag (i.e. SEC_OID_*). Many of the NSS API's\n\
11248     will accept an OID tag number instead of DER encoded OID in a SecItem.\n\
11249     One can easily convert between DER encoded OID's, tags, and their\n\
11250     string representation in dotted-decimal format. The enumerated OID\n\
11251     constants are the most efficient in most cases.\n\
11252 value\n\
11253     The value of the attribute (e.g. 'www.redhat.com').\n\
11254 \n\
11255 Examples::\n\
11256 \n\
11257     The AVA cn=www.redhat.com can be created in any of the follow ways:\n\
11258 \n\
11259     ava = nss.AVA('cn', 'www.redhat.com')\n\
11260     ava = nss.AVA(nss.SEC_OID_AVA_COMMON_NAME, 'www.redhat.com')\n\
11261     ava = nss.AVA('2.5.4.3', 'www.redhat.com')\n\
11262     ava = nss.AVA('OID.2.5.4.3', 'www.redhat.com')\n\
11263 ");
11264 
11265 static int
AVA_init(AVA * self,PyObject * args,PyObject * kwds)11266 AVA_init(AVA *self, PyObject *args, PyObject *kwds)
11267 {
11268     static char *kwlist[] = {"type", "value", NULL};
11269     PyObject *py_type = NULL;
11270     PyObject *py_value = NULL;
11271     PyObject *py_value_utf8 = NULL;
11272     int oid_tag = SEC_OID_UNKNOWN;
11273     int value_type;
11274     char *value_string;
11275 
11276     TraceMethodEnter(self);
11277 
11278     if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO:AVA", kwlist,
11279                                      &py_type, &py_value))
11280         return -1;
11281 
11282     if ((oid_tag = get_oid_tag_from_object(py_type)) == -1) {
11283         return -1;
11284     }
11285 
11286     if (oid_tag == SEC_OID_UNKNOWN) {
11287         PyErr_Format(PyExc_ValueError, "unable to convert to known OID");
11288         return -1;
11289     }
11290 
11291     if (PyBaseString_Check(py_value)) {
11292         py_value_utf8 =  PyBaseString_UTF8(py_value, "ava value");
11293 
11294         if ((value_string = PyBytes_AsString(py_value_utf8)) == NULL) {
11295             Py_DECREF(py_value_utf8);
11296             return -1;
11297         }
11298     } else {
11299         PyErr_Format(PyExc_TypeError, "AVA value must be a string, not %.200s",
11300                      Py_TYPE(py_type)->tp_name);
11301         return -1;
11302     }
11303 
11304     value_type = ava_oid_tag_to_value_type(oid_tag);
11305     if ((self->ava = CERT_CreateAVA(self->arena, oid_tag, value_type, value_string)) == NULL) {
11306         set_nspr_error("could not create AVA, oid tag = %d, value = \"%s\"",
11307                        oid_tag, value_string);
11308 	Py_XDECREF(py_value_utf8);
11309         return -1;
11310     }
11311 
11312     Py_XDECREF(py_value_utf8);
11313     return 0;
11314 }
11315 
11316 static PyObject *
AVA_repr(AVA * self)11317 AVA_repr(AVA *self)
11318 {
11319     PyObject *py_value_str;
11320 
11321     if ((py_value_str = CERTAVA_value_to_pystr(self->ava)) == NULL) {
11322         return PyUnicode_FromFormat("<%s object at %p>",
11323                                     Py_TYPE(self)->tp_name, self);
11324     }
11325     return py_value_str;
11326 }
11327 
11328 static PyTypeObject AVAType = {
11329     PyVarObject_HEAD_INIT(NULL, 0)
11330     "nss.nss.AVA",				/* tp_name */
11331     sizeof(AVA),				/* tp_basicsize */
11332     0,						/* tp_itemsize */
11333     (destructor)AVA_dealloc,			/* tp_dealloc */
11334     0,						/* tp_print */
11335     0,						/* tp_getattr */
11336     0,						/* tp_setattr */
11337     0,						/* tp_compare */
11338     (reprfunc)AVA_repr,				/* tp_repr */
11339     0,						/* tp_as_number */
11340     0,						/* tp_as_sequence */
11341     0,						/* tp_as_mapping */
11342     0,						/* tp_hash */
11343     0,						/* tp_call */
11344     0,						/* tp_str */
11345     0,						/* tp_getattro */
11346     0,						/* tp_setattro */
11347     0,						/* tp_as_buffer */
11348     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,	/* tp_flags */
11349     AVA_doc,					/* tp_doc */
11350     0,						/* tp_traverse */
11351     0,						/* tp_clear */
11352     (richcmpfunc)AVA_richcompare,		/* tp_richcompare */
11353     0,						/* tp_weaklistoffset */
11354     0,						/* tp_iter */
11355     0,						/* tp_iternext */
11356     AVA_methods,				/* tp_methods */
11357     AVA_members,				/* tp_members */
11358     AVA_getseters,				/* tp_getset */
11359     0,						/* tp_base */
11360     0,						/* tp_dict */
11361     0,						/* tp_descr_get */
11362     0,						/* tp_descr_set */
11363     0,						/* tp_dictoffset */
11364     (initproc)AVA_init,				/* tp_init */
11365     0,						/* tp_alloc */
11366     AVA_new,					/* tp_new */
11367 };
11368 
11369 PyObject *
AVA_new_from_CERTAVA(CERTAVA * ava)11370 AVA_new_from_CERTAVA(CERTAVA *ava)
11371 {
11372     AVA *self = NULL;
11373 
11374     TraceObjNewEnter(NULL);
11375 
11376     if ((self = (AVA *) AVAType.tp_new(&AVAType, NULL, NULL)) == NULL)
11377         return NULL;
11378 
11379     if ((self->ava = (CERTAVA*) PORT_ArenaZNew(self->arena, CERTAVA)) == NULL) {
11380         set_nspr_error(NULL);
11381         Py_CLEAR(self);
11382         return NULL;
11383     }
11384 
11385     if (SECITEM_CopyItem(NULL, &self->ava->type, &ava->type) != SECSuccess) {
11386         set_nspr_error(NULL);
11387         Py_CLEAR(self);
11388         return NULL;
11389     }
11390     self->ava->type.type = siDEROID; /* NSS often fails to set this so force it */
11391 
11392     if (SECITEM_CopyItem(NULL, &self->ava->value, &ava->value) != SECSuccess) {
11393         set_nspr_error(NULL);
11394         Py_CLEAR(self);
11395         return NULL;
11396     }
11397 
11398     TraceObjNewLeave(self);
11399     return (PyObject *) self;
11400 }
11401 
11402 /* ========================================================================== */
11403 /* =============================== RDN Class ================================ */
11404 /* ========================================================================== */
11405 
11406 /*
11407  * Note: CERT_AddAVA, CERT_AddRDN, CERT_CompareRDN, CERT_CopyRDN, CERT_CreateName
11408  * CERT_CreateRDN, CERT_DestroyRDN are defined in cert.h
11409  *
11410  * But only CERT_AddRDN, CERT_CopyRDN, CERT_CreateName, CERT_CreateRDN
11411  * are exported by nss.def
11412  *
11413  * That means CERT_AddAVA, CERT_CompareRDN, CERT_DestroyRDN
11414  * are defined as public but aren't. Note CERT_DestroyRDN has no implementation.
11415  */
11416 
11417 /* ============================ Attribute Access ============================ */
11418 
11419 static
11420 PyGetSetDef RDN_getseters[] = {
11421     {NULL}  /* Sentinel */
11422 };
11423 
11424 static PyMemberDef RDN_members[] = {
11425     {NULL}  /* Sentinel */
11426 };
11427 
11428 /* ============================== Class Methods ============================= */
11429 
11430 /*
11431  * Compares two CERTRDN's, returns -1 if a < b, 0 if a == b, 1 if a > b
11432  * If error, returns -2
11433  */
11434 static int
CERTRDN_compare(CERTRDN * a,CERTRDN * b)11435 CERTRDN_compare(CERTRDN *a, CERTRDN *b)
11436 {
11437     SECComparison cmp_result;
11438     int a_len, b_len;
11439     CERTAVA **a_avas, *a_ava;
11440     CERTAVA **b_avas, *b_ava;
11441 
11442     if (a == NULL && b == NULL) return 0;
11443     if (a == NULL && b != NULL) return -1;
11444     if (a != NULL && b == NULL) return 1;
11445 
11446     a_len = CERTRDN_ava_count(a);
11447     b_len = CERTRDN_ava_count(b);
11448 
11449     if (a_len < b_len) return -1;
11450     if (a_len > b_len) return  1;
11451 
11452     for (a_avas = a->avas, b_avas = b->avas;
11453          a_avas && (a_ava = *a_avas) && b_avas && (b_ava = *b_avas);
11454          a_avas++, b_avas++) {
11455         if ((cmp_result = CERTAVA_compare(a_ava, b_ava)) != 0) {
11456             return cmp_result;
11457         }
11458     }
11459     return 0;
11460 }
11461 
11462 static PyObject *
RDN_richcompare(RDN * self,RDN * other,int op)11463 RDN_richcompare(RDN *self, RDN *other, int op)
11464 {
11465     int cmp_result;
11466 
11467     if (!PyRDN_Check(other)) {
11468         PyErr_SetString(PyExc_TypeError, "Bad type, must be RDN");
11469         return NULL;
11470     }
11471 
11472     cmp_result = CERTRDN_compare(self->rdn, other->rdn);
11473     if (cmp_result == -2) {
11474         return NULL;
11475     }
11476     RETURN_COMPARE_RESULT(op, cmp_result)
11477 }
11478 
11479 static int
RDN_contains(RDN * self,PyObject * arg)11480 RDN_contains(RDN *self, PyObject *arg)
11481 {
11482     int oid_tag;
11483 
11484     TraceMethodEnter(self);
11485 
11486     oid_tag = get_oid_tag_from_object(arg);
11487     if (oid_tag == SEC_OID_UNKNOWN || oid_tag == -1) {
11488         return 0;
11489     }
11490 
11491     if (CERTRDN_has_tag(self->rdn, oid_tag)) {
11492         return 1;
11493     } else {
11494         return 0;
11495     }
11496 }
11497 
11498 PyDoc_STRVAR(RDN_has_key_doc,
11499 "has_key(arg) -> bool\n\
11500 \n\
11501 :Parameters:\n\
11502     arg : string or integer\n\
11503         canonical name (e.g. 'cn') or oid dotted-decimal or\n\
11504         SEC_OID_* enumeration constant\n\
11505 \n\
11506 return True if RDN has an AVA whose oid can be identified by arg.\n\
11507 ");
11508 
11509 static PyObject *
RDN_has_key(RDN * self,PyObject * args)11510 RDN_has_key(RDN *self, PyObject *args)
11511 {
11512     PyObject *arg;
11513 
11514     TraceMethodEnter(self);
11515 
11516     if (!PyArg_ParseTuple(args, "O:has_key",
11517                           &arg))
11518         return NULL;
11519 
11520     if (RDN_contains(self, arg)) {
11521         Py_RETURN_TRUE;
11522     } else {
11523         Py_RETURN_FALSE;
11524     }
11525 }
11526 
11527 /* =========================== Sequence Protocol ============================ */
11528 
11529 static Py_ssize_t
CERTRDN_ava_count(CERTRDN * rdn)11530 CERTRDN_ava_count(CERTRDN *rdn)
11531 {
11532     Py_ssize_t count;
11533     CERTAVA **avas;
11534 
11535     if (!rdn) return 0;
11536     for (avas = rdn->avas, count = 0; *avas; avas++, count++);
11537 
11538     return count;
11539 }
11540 
11541 static Py_ssize_t
RDN_length(RDN * self)11542 RDN_length(RDN *self)
11543 {
11544     return CERTRDN_ava_count(self->rdn);
11545 }
11546 
11547 static PyObject *
RDN_item(RDN * self,register Py_ssize_t i)11548 RDN_item(RDN *self, register Py_ssize_t i)
11549 {
11550     Py_ssize_t count = 0;
11551     CERTAVA **avas;
11552 
11553     if (i < 0 || !self->rdn || self->rdn->avas == NULL) {
11554         PyErr_SetString(PyExc_IndexError, "RDN index out of range");
11555         return NULL;
11556     }
11557 
11558     for (avas = self->rdn->avas, count = 0; *avas && count < i; avas++, count++);
11559 
11560     if (!*avas) {
11561         PyErr_SetString(PyExc_IndexError, "RDN index out of range");
11562         return NULL;
11563     }
11564 
11565     return AVA_new_from_CERTAVA(*avas);
11566 }
11567 
11568 
11569 static bool
CERTRDN_has_tag(CERTRDN * rdn,int tag)11570 CERTRDN_has_tag(CERTRDN *rdn, int tag)
11571 {
11572     CERTAVA **avas;
11573     CERTAVA *ava = NULL;
11574 
11575     if (!rdn) return false;
11576     for (avas = rdn->avas; avas && (ava = *avas); avas++) {
11577         int ava_tag = CERT_GetAVATag(ava);
11578         if (tag == ava_tag) {
11579             return true;
11580         }
11581     }
11582     return false;
11583 }
11584 
11585 static PyObject *
CERTRDN_get_matching_tag_list(CERTRDN * rdn,int tag)11586 CERTRDN_get_matching_tag_list(CERTRDN *rdn, int tag)
11587 {
11588     PyObject *list = NULL;
11589     PyObject *py_ava = NULL;
11590     CERTAVA **avas, *ava;
11591 
11592     if ((list = PyList_New(0)) == NULL) {
11593         return NULL;
11594     }
11595 
11596     if (!rdn) {
11597         return list;
11598     }
11599 
11600     for (avas = rdn->avas; avas && (ava = *avas); avas++) {
11601         int ava_tag = CERT_GetAVATag(ava);
11602         if (tag == ava_tag) {
11603             if ((py_ava = AVA_new_from_CERTAVA(ava)) == NULL) {
11604                 Py_DECREF(list);
11605                 return NULL;
11606             }
11607             PyList_Append(list, py_ava);
11608         }
11609     }
11610 
11611     return list;
11612 }
11613 static PyObject*
RDN_subscript(RDN * self,PyObject * item)11614 RDN_subscript(RDN *self, PyObject* item)
11615 {
11616     PyObject* result;
11617 
11618     if (PyIndex_Check(item)) {
11619         Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
11620 
11621         if (i == -1 && PyErr_Occurred())
11622             return NULL;
11623         if (i < 0)
11624             i += RDN_length(self);
11625         return RDN_item(self, i);
11626     } else if (PySlice_Check(item)) {
11627         Py_ssize_t start, stop, step, slicelength, cur, i;
11628         PyObject* py_ava;
11629 
11630 #if PY_MAJOR_VERSION >= 3
11631         /* The only difference between Py2 and Py3 is Py2 needs (PySliceObject *) cast on 1st parameter */
11632         if (PySlice_GetIndicesEx(item, RDN_length(self),
11633 				 &start, &stop, &step, &slicelength) < 0) {
11634             return NULL;
11635         }
11636 #else
11637         if (PySlice_GetIndicesEx((PySliceObject *)item, RDN_length(self),
11638 				 &start, &stop, &step, &slicelength) < 0) {
11639             return NULL;
11640         }
11641 #endif
11642 
11643         if (slicelength <= 0) {
11644             return PyList_New(0);
11645         } else {
11646             result = PyList_New(slicelength);
11647             if (!result) return NULL;
11648 
11649             for (cur = start, i = 0; i < slicelength; cur += step, i++) {
11650                 /* We don't need to bump the ref count because RDN_item
11651                  * returns a new object */
11652                 py_ava = RDN_item(self, cur);
11653                 if (PyList_SetItem(result, i, py_ava) == -1) {
11654                     Py_DECREF(result);
11655                     return NULL;
11656                 }
11657             }
11658             return result;
11659 	}
11660     } else if (PyBaseString_Check(item) || PySecItem_Check(item)) {
11661         int oid_tag;
11662 
11663         if ((oid_tag = get_oid_tag_from_object(item)) == -1) {
11664             return NULL;
11665         }
11666 
11667         if (oid_tag == SEC_OID_UNKNOWN) {
11668             if (PyBaseString_Check(item)) {
11669                 PyObject *name_utf8 = PyBaseString_UTF8(item, "oid");
11670                 PyErr_Format(PyExc_KeyError, "oid name unknown: \"%s\"",
11671                              PyBytes_AS_STRING(name_utf8));
11672                 Py_DECREF(name_utf8);
11673                 return NULL;
11674             } else {
11675                 PyErr_SetString(PyExc_KeyError, "oid unknown");
11676                 return NULL;
11677             }
11678         }
11679 
11680         if ((result = CERTRDN_get_matching_tag_list(self->rdn, oid_tag)) == NULL) {
11681             return NULL;
11682         }
11683 
11684         if (PyList_Size(result) == 0) {
11685             Py_DECREF(result);
11686             if (PyBaseString_Check(item)) {
11687                 PyObject *name_utf8 = PyBaseString_UTF8(item, "oid");
11688                 PyErr_Format(PyExc_KeyError, "oid name not found: \"%s\"",
11689                              PyBytes_AS_STRING(name_utf8));
11690                 Py_DECREF(name_utf8);
11691                 return NULL;
11692             } else {
11693                 PyErr_SetString(PyExc_KeyError, "oid not found");
11694                 return NULL;
11695             }
11696         } else {
11697             return result;
11698         }
11699     } else {
11700         PyErr_Format(PyExc_TypeError,
11701                      "indices must be integers or strings, not %.200s",
11702                      Py_TYPE(item)->tp_name);
11703         return NULL;
11704     }
11705     return NULL;
11706 }
11707 
11708 static PyObject *
RDN_repr(RDN * self)11709 RDN_repr(RDN *self)
11710 {
11711     return CERTRDN_to_pystr(self->rdn);
11712 }
11713 
11714 static PyMethodDef RDN_methods[] = {
11715     {"has_key", (PyCFunction)RDN_has_key, METH_VARARGS, RDN_has_key_doc},
11716     {NULL, NULL}  /* Sentinel */
11717 };
11718 
11719 /* =========================== Class Construction =========================== */
11720 
11721 static PyObject *
RDN_new(PyTypeObject * type,PyObject * args,PyObject * kwds)11722 RDN_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
11723 {
11724     RDN *self;
11725 
11726     TraceObjNewEnter(type);
11727 
11728     if ((self = (RDN *)type->tp_alloc(type, 0)) == NULL) {
11729         return NULL;
11730     }
11731 
11732     if ((self->arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE)) == NULL) {
11733         type->tp_free(self);
11734         return set_nspr_error(NULL);
11735     }
11736 
11737     self->rdn = NULL;
11738 
11739     TraceObjNewLeave(self);
11740 
11741     return (PyObject *)self;
11742 }
11743 
11744 static void
RDN_dealloc(RDN * self)11745 RDN_dealloc(RDN* self)
11746 {
11747     TraceMethodEnter(self);
11748 
11749     if (self->arena) {
11750         PORT_FreeArena(self->arena, PR_FALSE);
11751     }
11752 
11753     Py_TYPE(self)->tp_free((PyObject*)self);
11754 }
11755 
11756 PyDoc_STRVAR(RDN_doc,
11757 "An object representing an X501 Relative Distinguished Name (e.g. RDN).\n\
11758 \n\
11759 RDN objects contain an ordered list of `AVA` objects. \n\
11760 \n\
11761 Examples::\n\
11762 \n\
11763     RDN()\n\
11764     RDN(nss.AVA('cn', 'www.redhat.com'))\n\
11765     RDN([ava0, ava1])\n\
11766 \n\
11767 The RDN object constructor may be invoked with zero or more\n\
11768 `AVA` objects, or you may optionally pass a list or tuple of `AVA`\n\
11769 objects.\n\
11770 \n\
11771 RDN objects contain an ordered list of `AVA` objects. The\n\
11772 RDN object has both sequence and mapping behaviors with respect to\n\
11773 the AVA's they contain. Thus you can index an AVA by position, by\n\
11774 name, or by SecItem (if it's an OID). You can iterate over the list,\n\
11775 get it's length or take a slice.\n\
11776 \n\
11777 If you index by string the string may be either a canonical name for\n\
11778 the AVA type (e.g. 'cn') or the dotted-decimal notation for the OID\n\
11779 (e.g. 2.5.4.3). There may be multiple AVA's in a RDN whose type matches\n\
11780 (e.g. OU=engineering+OU=boston). It is not common to have more than\n\
11781 one AVA in a RDN with the same type. However because of the possiblity\n\
11782 of being multi-valued when indexing by type a list is always returned\n\
11783 containing the matching AVA's. Thus::\n\
11784 \n\
11785     rdn = nss.RDN(nss.AVA('OU', 'engineering'))\n\
11786     rdn['ou']\n\
11787         returns [AVA('OU=engineering')\n\
11788 \n\
11789     rdn = nss.RDN(nss.AVA('OU', 'engineering'), nss.AVA('OU', 'boston'))\n\
11790     rdn['ou']\n\
11791         returns [AVA('OU=boston'), AVA('OU=engineering')]\n\
11792 \n\
11793 Examples::\n\
11794 \n\
11795     rdn = nss.RDN(nss.AVA('cn', 'www.redhat.com'))\n\
11796     str(rdn)\n\
11797        returns 'CN=www.redhat.com'\n\
11798     rdn[0]\n\
11799        returns an `AVA` object with the value C=US\n\
11800     rdn['cn']\n\
11801         returns a list comprised of an `AVA` object with the value CN=www.redhat.com\n\
11802     rdn['2.5.4.3']\n\
11803         returns a list comprised of an `AVA` object with the value CN=www.redhat.com\n\
11804         because 2.5.4.3 is the dotted-decimal OID for common name (i.e. cn)\n\
11805     rdn.has_key('cn')\n\
11806         returns True because the RDN has a common name RDN\n\
11807     rdn.has_key('2.5.4.3')\n\
11808         returns True because the RDN has a common name AVA\n\
11809         because 2.5.4.3 is the dotted-decimal OID for common name (i.e. cn)\n\
11810     len(rdn)\n\
11811        returns 1 because there is one `AVA` object in it\n\
11812     list(rdn)\n\
11813        returns a list of each `AVA` object in it\n\
11814 \n\
11815 ");
11816 
11817 static int
RDN_init(RDN * self,PyObject * args,PyObject * kwds)11818 RDN_init(RDN *self, PyObject *args, PyObject *kwds)
11819 {
11820     PyObject *sequence, *item;
11821     Py_ssize_t sequence_len, i;
11822     AVA *py_ava;
11823     CERTAVA *ava_arg[MAX_AVAS+1];  /* +1 for NULL terminator */
11824 
11825     TraceMethodEnter(self);
11826 
11827     if (PyTuple_GET_SIZE(args) > 0) {
11828         sequence = PyTuple_GetItem(args, 0);
11829         if (!(PyTuple_Check(sequence) || PyList_Check(sequence))) {
11830             sequence = args;
11831         }
11832         sequence_len = PySequence_Length(sequence);
11833         if (sequence_len > MAX_AVAS) {
11834             PyErr_Format(PyExc_ValueError, "to many AVA items, maximum is %d, received %zd",
11835                          MAX_AVAS-1, sequence_len);
11836             return -1;
11837         }
11838         for (i = 0; i < sequence_len && i < MAX_AVAS; i++) {
11839             item = PySequence_ITEM(sequence, i);
11840             if (PyAVA_Check(item)) {
11841                 py_ava = (AVA *)item;
11842                 if ((ava_arg[i] = CERT_CopyAVA(self->arena, py_ava->ava)) == NULL) {
11843                     set_nspr_error(NULL);
11844                     Py_DECREF(item);
11845                     return -1;
11846                 }
11847                 Py_DECREF(item);
11848             } else {
11849                 PyErr_Format(PyExc_TypeError, "item %zd must be an AVA object, not %.200s",
11850                              i, Py_TYPE(item)->tp_name);
11851                 Py_DECREF(item);
11852                 return -1;
11853                 }
11854             }
11855 
11856         for (; i < MAX_AVAS+1; i++) ava_arg[i] = NULL;
11857 
11858         if ((self->rdn = CERT_CreateRDN(self->arena,
11859                                         ava_arg[0], ava_arg[1], ava_arg[2], ava_arg[3],
11860                                         ava_arg[4], ava_arg[5], ava_arg[6], ava_arg[7],
11861                                         ava_arg[8], ava_arg[9], ava_arg[10])) == NULL) {
11862             set_nspr_error(NULL);
11863             return -1;
11864         }
11865     }
11866 
11867     return 0;
11868 }
11869 
11870 static PySequenceMethods RDN_as_sequence = {
11871     (lenfunc)RDN_length,			/* sq_length */
11872     0,						/* sq_concat */
11873     0,						/* sq_repeat */
11874     (ssizeargfunc)RDN_item,			/* sq_item */
11875     0,						/* sq_slice */
11876     0,						/* sq_ass_item */
11877     0,						/* sq_ass_slice */
11878     (objobjproc)RDN_contains,			/* sq_contains */
11879     0,						/* sq_inplace_concat */
11880     0,						/* sq_inplace_repeat */
11881 };
11882 
11883 static PyMappingMethods RDN_as_mapping = {
11884     (lenfunc)RDN_length,			/* mp_length */
11885     (binaryfunc)RDN_subscript,			/* mp_subscript */
11886     0,						/* mp_ass_subscript */
11887 };
11888 
11889 static PyTypeObject RDNType = {
11890     PyVarObject_HEAD_INIT(NULL, 0)
11891     "nss.nss.RDN",				/* tp_name */
11892     sizeof(RDN),				/* tp_basicsize */
11893     0,						/* tp_itemsize */
11894     (destructor)RDN_dealloc,			/* tp_dealloc */
11895     0,						/* tp_print */
11896     0,						/* tp_getattr */
11897     0,						/* tp_setattr */
11898     0,						/* tp_compare */
11899     (reprfunc)RDN_repr,				/* tp_repr */
11900     0,						/* tp_as_number */
11901     &RDN_as_sequence,				/* tp_as_sequence */
11902     &RDN_as_mapping,				/* tp_as_mapping */
11903     0,						/* tp_hash */
11904     0,						/* tp_call */
11905     0,						/* tp_str */
11906     0,						/* tp_getattro */
11907     0,						/* tp_setattro */
11908     0,						/* tp_as_buffer */
11909     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,	/* tp_flags */
11910     RDN_doc,					/* tp_doc */
11911     0,						/* tp_traverse */
11912     0,						/* tp_clear */
11913     (richcmpfunc)RDN_richcompare,		/* tp_richcompare */
11914     0,						/* tp_weaklistoffset */
11915     0,						/* tp_iter */
11916     0,						/* tp_iternext */
11917     RDN_methods,				/* tp_methods */
11918     RDN_members,				/* tp_members */
11919     RDN_getseters,				/* tp_getset */
11920     0,						/* tp_base */
11921     0,						/* tp_dict */
11922     0,						/* tp_descr_get */
11923     0,						/* tp_descr_set */
11924     0,						/* tp_dictoffset */
11925     (initproc)RDN_init,				/* tp_init */
11926     0,						/* tp_alloc */
11927     RDN_new,					/* tp_new */
11928 };
11929 
11930 PyObject *
RDN_new_from_CERTRDN(CERTRDN * rdn)11931 RDN_new_from_CERTRDN(CERTRDN *rdn)
11932 {
11933     RDN *self = NULL;
11934     int i;
11935     CERTAVA *ava_arg[MAX_AVAS+1];  /* +1 for NULL terminator */
11936     CERTAVA **avas, *ava;
11937 
11938     TraceObjNewEnter(NULL);
11939 
11940     if ((self = (RDN *) RDNType.tp_new(&RDNType, NULL, NULL)) == NULL) {
11941         return NULL;
11942     }
11943 
11944     i = 0;
11945     if (rdn) {
11946         for (avas = rdn->avas; i < MAX_AVAS && avas && (ava = *avas); avas++, i++) {
11947             if ((ava_arg[i] = CERT_CopyAVA(self->arena, ava)) == NULL) {
11948                 set_nspr_error(NULL);
11949                 Py_CLEAR(self);
11950                 return NULL;
11951             }
11952         }
11953     }
11954 
11955     for (; i < MAX_AVAS+1; i++) ava_arg[i] = NULL;
11956 
11957     if ((self->rdn = CERT_CreateRDN(self->arena,
11958                                     ava_arg[0], ava_arg[1], ava_arg[2], ava_arg[3],
11959                                     ava_arg[4], ava_arg[5], ava_arg[6], ava_arg[7],
11960                                     ava_arg[8], ava_arg[9], ava_arg[10])) == NULL) {
11961         set_nspr_error(NULL);
11962         Py_CLEAR(self);
11963         return NULL;
11964     }
11965 
11966     TraceObjNewLeave(self);
11967     return (PyObject *) self;
11968 }
11969 
11970 /* ========================================================================== */
11971 /* =============================== DN Class ================================= */
11972 /* ========================================================================== */
11973 
11974 /*
11975  * NSS WART
11976  *
11977  * CERT_CopyRDN() does not return a new CERTRDN, requires calling CERT_CreateRDN()
11978  *
11979  * CERT_CreateName() does not copy it's rdn arguments, must call CERT_CopyRDN()
11980  *
11981  * CERT_CreateName() does not allow you to pass in an arena, it creates one
11982  * and stores it internally. But to call CERT_CreateName() you have to call
11983  * CERT_CopyRDN() which requires an arena. This means a CERTName object has to
11984  * have 2 arenas when one would have sufficed, it also means more bookkeeping
11985  * to manage the second unnecessary arena.
11986  *
11987  * CERT_CopyAVA() doesn't return SECStatus unlike other copy routines.
11988  */
11989 
11990 /*
11991  * All these are defined in cert.h and all are exported in nss.def
11992  *
11993  * CERT_AsciiToName
11994  * CERT_NameToAscii
11995  * CERT_NameToAsciiInvertible
11996  * CERT_CreateName
11997  * CERT_CopyName
11998  * CERT_DestroyName
11999  * CERT_AddRDN
12000  * CERT_CompareName
12001  * CERT_FormatName
12002  * CERT_GetCertEmailAddress
12003  * CERT_GetCommonName
12004  * CERT_GetCountryName
12005  * CERT_GetLocalityName
12006  * CERT_GetStateName
12007  * CERT_GetOrgName
12008  * CERT_GetOrgUnitName
12009  * CERT_GetDomainComponentName
12010  * CERT_GetCertUid
12011  */
12012 
12013 static bool
CERTName_has_tag(CERTName * name,int tag)12014 CERTName_has_tag(CERTName *name, int tag)
12015 {
12016     CERTRDN **rdns, *rdn;
12017     CERTAVA **avas, *ava;
12018 
12019     if (!name) return false;
12020     for (rdns = name->rdns; rdns && (rdn = *rdns); rdns++) {
12021 	for (avas = rdn->avas; avas && (ava = *avas); avas++) {
12022 	    int ava_tag = CERT_GetAVATag(ava);
12023 	    if (tag == ava_tag) {
12024                 return true;
12025 	    }
12026 	}
12027     }
12028 
12029     return false;
12030 }
12031 
12032 static PyObject *
CERTName_get_matching_tag_list(CERTName * name,int tag)12033 CERTName_get_matching_tag_list(CERTName *name, int tag)
12034 {
12035     PyObject *list = NULL;
12036     PyObject *py_rdn = NULL;
12037     CERTRDN **rdns, *rdn;
12038     CERTAVA **avas, *ava;
12039 
12040     if ((list = PyList_New(0)) == NULL) {
12041         return NULL;
12042     }
12043 
12044     if (!name) {
12045         return list;
12046     }
12047 
12048     for (rdns = name->rdns; rdns && (rdn = *rdns); rdns++) {
12049 	for (avas = rdn->avas; avas && (ava = *avas); avas++) {
12050 	    int ava_tag = CERT_GetAVATag(ava);
12051 	    if (tag == ava_tag) {
12052                 if ((py_rdn = RDN_new_from_CERTRDN(rdn)) == NULL) {
12053                     Py_DECREF(list);
12054                     return NULL;
12055                 }
12056                 PyList_Append(list, py_rdn);
12057                 break;
12058 	    }
12059 	}
12060     }
12061 
12062     return list;
12063 }
12064 
12065 static PyObject*
DN_subscript(DN * self,PyObject * item)12066 DN_subscript(DN *self, PyObject* item)
12067 {
12068     PyObject* result = NULL;
12069 
12070     if (PyIndex_Check(item)) {
12071         Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
12072 
12073         if (i == -1 && PyErr_Occurred())
12074             return NULL;
12075         if (i < 0)
12076             i += DN_length(self);
12077         return DN_item(self, i);
12078     } else if (PySlice_Check(item)) {
12079         Py_ssize_t start, stop, step, slicelength, cur, i;
12080         PyObject* py_ava;
12081 
12082 #if PY_MAJOR_VERSION >= 3
12083         /* The only difference between Py2 and Py3 is Py2 needs (PySliceObject *) cast on 1st parameter */
12084         if (PySlice_GetIndicesEx(item, DN_length(self),
12085 				 &start, &stop, &step, &slicelength) < 0) {
12086             return NULL;
12087         }
12088 #else
12089         if (PySlice_GetIndicesEx((PySliceObject *)item, DN_length(self),
12090 				 &start, &stop, &step, &slicelength) < 0) {
12091             return NULL;
12092         }
12093 #endif
12094 
12095         if (slicelength <= 0) {
12096             return PyList_New(0);
12097         } else {
12098             result = PyList_New(slicelength);
12099             if (!result) return NULL;
12100 
12101             for (cur = start, i = 0; i < slicelength; cur += step, i++) {
12102                 /* We don't need to bump the ref count because RDN_item
12103                  * returns a new object */
12104                 py_ava = DN_item(self, cur);
12105                 if (PyList_SetItem(result, i, py_ava) == -1) {
12106                     Py_DECREF(result);
12107                     return NULL;
12108                 }
12109             }
12110             return result;
12111 	}
12112     } else if (PyBaseString_Check(item) || PySecItem_Check(item)) {
12113         int oid_tag;
12114 
12115         if ((oid_tag = get_oid_tag_from_object(item)) == -1) {
12116             return NULL;
12117         }
12118 
12119         if (oid_tag == SEC_OID_UNKNOWN) {
12120             if (PyBaseString_Check(item)) {
12121                 PyObject *name_utf8 = PyBaseString_UTF8(item, "oid");
12122                 PyErr_Format(PyExc_KeyError, "oid name unknown: \"%s\"",
12123                              PyBytes_AS_STRING(name_utf8));
12124                 Py_DECREF(name_utf8);
12125                 return NULL;
12126             } else {
12127                 PyErr_SetString(PyExc_KeyError, "oid unknown");
12128                 return NULL;
12129             }
12130         }
12131 
12132         if ((result = CERTName_get_matching_tag_list(&self->name, oid_tag)) == NULL) {
12133             return NULL;
12134         }
12135 
12136         if (PyList_Size(result) == 0) {
12137             Py_DECREF(result);
12138             if (PyBaseString_Check(item)) {
12139                 PyObject *name_utf8 = PyBaseString_UTF8(item, "oid");
12140                 PyErr_Format(PyExc_KeyError, "oid name not found: \"%s\"",
12141                              PyBytes_AS_STRING(name_utf8));
12142                 Py_DECREF(name_utf8);
12143                 return NULL;
12144             } else {
12145                 PyErr_SetString(PyExc_KeyError, "oid not found");
12146                 return NULL;
12147             }
12148         } else {
12149             return result;
12150         }
12151     } else {
12152         PyErr_Format(PyExc_TypeError,
12153                      "indices must be integers or strings, not %.200s",
12154                      Py_TYPE(item)->tp_name);
12155         return NULL;
12156     }
12157     return NULL;
12158 }
12159 
12160 static int
DN_contains(DN * self,PyObject * arg)12161 DN_contains(DN *self, PyObject *arg)
12162 {
12163     int oid_tag;
12164 
12165     TraceMethodEnter(self);
12166 
12167     oid_tag = get_oid_tag_from_object(arg);
12168     if (oid_tag == SEC_OID_UNKNOWN || oid_tag == -1) {
12169         return 0;
12170     }
12171 
12172     if (CERTName_has_tag(&self->name, oid_tag)) {
12173         return 1;
12174     } else {
12175         return 0;
12176     }
12177 }
12178 
12179 PyDoc_STRVAR(DN_has_key_doc,
12180 "has_key(arg) -> bool\n\
12181 \n\
12182 :Parameters:\n\
12183     arg : string or integer\n\
12184         canonical name (e.g. 'cn') or oid dotted-decimal or\n\
12185         SEC_OID_* enumeration constant\n\
12186 \n\
12187 return True if Name has an AVA whose oid can be identified by arg.\n\
12188 ");
12189 
12190 static PyObject *
DN_has_key(DN * self,PyObject * args)12191 DN_has_key(DN *self, PyObject *args)
12192 {
12193     PyObject *arg;
12194 
12195     TraceMethodEnter(self);
12196 
12197     if (!PyArg_ParseTuple(args, "O:has_key",
12198                           &arg))
12199         return NULL;
12200 
12201     if (DN_contains(self, arg)) {
12202         Py_RETURN_TRUE;
12203     } else {
12204         Py_RETURN_FALSE;
12205     }
12206 }
12207 
12208 /* =========================== Sequence Protocol ============================ */
12209 
12210 static Py_ssize_t
CERTName_rdn_count(CERTName * name)12211 CERTName_rdn_count(CERTName *name)
12212 {
12213     Py_ssize_t count = 0;
12214     CERTRDN **rdns;
12215 
12216     for (rdns = name->rdns, count = 0; *rdns; rdns++, count++);
12217 
12218     return count;
12219 }
12220 
12221 static Py_ssize_t
DN_length(DN * self)12222 DN_length(DN *self)
12223 {
12224     return CERTName_rdn_count(&self->name);
12225 }
12226 
12227 static PyObject *
DN_item(DN * self,register Py_ssize_t i)12228 DN_item(DN *self, register Py_ssize_t i)
12229 {
12230     Py_ssize_t count = 0;
12231     CERTRDN **rdns;
12232 
12233     if (i < 0 || self->name.rdns == NULL) {
12234         PyErr_SetString(PyExc_IndexError, "DN index out of range");
12235         return NULL;
12236     }
12237 
12238     for (rdns = self->name.rdns, count = 0; *rdns && count < i; rdns++, count++);
12239 
12240     if (!*rdns) {
12241         PyErr_SetString(PyExc_IndexError, "DN index out of range");
12242         return NULL;
12243     }
12244 
12245     return RDN_new_from_CERTRDN(*rdns);
12246 }
12247 
12248 /* ============================ Attribute Access ============================ */
12249 
12250 static PyObject *
DN_get_email_address(DN * self,void * closure)12251 DN_get_email_address(DN *self, void *closure)
12252 {
12253     char *value;
12254 
12255     TraceMethodEnter(self);
12256 
12257     if ((value = CERT_GetCertEmailAddress(&self->name)) == NULL) {
12258         Py_RETURN_NONE;
12259     }
12260     return PyUnicode_FromString(value);
12261 }
12262 
12263 static PyObject *
DN_get_common_name(DN * self,void * closure)12264 DN_get_common_name(DN *self, void *closure)
12265 {
12266     char *value;
12267 
12268     TraceMethodEnter(self);
12269 
12270     if ((value = CERT_GetCommonName(&self->name)) == NULL) {
12271         Py_RETURN_NONE;
12272     }
12273     return PyUnicode_FromString(value);
12274 }
12275 
12276 static PyObject *
DN_get_country_name(DN * self,void * closure)12277 DN_get_country_name(DN *self, void *closure)
12278 {
12279     char *value;
12280 
12281     TraceMethodEnter(self);
12282 
12283     if ((value = CERT_GetCountryName(&self->name)) == NULL) {
12284         Py_RETURN_NONE;
12285     }
12286     return PyUnicode_FromString(value);
12287 }
12288 
12289 static PyObject *
DN_get_locality_name(DN * self,void * closure)12290 DN_get_locality_name(DN *self, void *closure)
12291 {
12292     char *value;
12293 
12294     TraceMethodEnter(self);
12295 
12296     if ((value = CERT_GetLocalityName(&self->name)) == NULL) {
12297         Py_RETURN_NONE;
12298     }
12299     return PyUnicode_FromString(value);
12300 }
12301 
12302 static PyObject *
DN_get_state_name(DN * self,void * closure)12303 DN_get_state_name(DN *self, void *closure)
12304 {
12305     char *value;
12306 
12307     TraceMethodEnter(self);
12308 
12309     if ((value = CERT_GetStateName(&self->name)) == NULL) {
12310         Py_RETURN_NONE;
12311     }
12312     return PyUnicode_FromString(value);
12313 }
12314 
12315 static PyObject *
DN_get_org_name(DN * self,void * closure)12316 DN_get_org_name(DN *self, void *closure)
12317 {
12318     char *value;
12319 
12320     TraceMethodEnter(self);
12321 
12322     if ((value = CERT_GetOrgName(&self->name)) == NULL) {
12323         Py_RETURN_NONE;
12324     }
12325     return PyUnicode_FromString(value);
12326 }
12327 
12328 static PyObject *
DN_get_org_unit_name(DN * self,void * closure)12329 DN_get_org_unit_name(DN *self, void *closure)
12330 {
12331     char *value;
12332 
12333     TraceMethodEnter(self);
12334 
12335     if ((value = CERT_GetOrgUnitName(&self->name)) == NULL) {
12336         Py_RETURN_NONE;
12337     }
12338     return PyUnicode_FromString(value);
12339 }
12340 
12341 static PyObject *
DN_get_domain_component_name(DN * self,void * closure)12342 DN_get_domain_component_name(DN *self, void *closure)
12343 {
12344     char *value;
12345 
12346     TraceMethodEnter(self);
12347 
12348     if ((value = CERT_GetDomainComponentName(&self->name)) == NULL) {
12349         Py_RETURN_NONE;
12350     }
12351     return PyUnicode_FromString(value);
12352 }
12353 
12354 static PyObject *
DN_get_cert_uid(DN * self,void * closure)12355 DN_get_cert_uid(DN *self, void *closure)
12356 {
12357     char *value;
12358 
12359     TraceMethodEnter(self);
12360 
12361     if ((value = CERT_GetCertUid(&self->name)) == NULL) {
12362         Py_RETURN_NONE;
12363     }
12364     return PyUnicode_FromString(value);
12365 }
12366 
12367 static
12368 PyGetSetDef DN_getseters[] = {
12369     {"email_address", (getter)DN_get_email_address, (setter)NULL,
12370      "Returns the email address member as a string. Returns None if not found.", NULL},
12371     {"common_name", (getter)DN_get_common_name, (setter)NULL,
12372      "Returns the common name member (i.e. CN) as a string. Returns None if not found.", NULL},
12373     {"country_name", (getter)DN_get_country_name, (setter)NULL,
12374      "Returns the country name member (i.e. C) as a string. Returns None if not found.", NULL},
12375     {"locality_name", (getter)DN_get_locality_name, (setter)NULL,
12376      "Returns the locality name member (i.e. L) as a string. Returns None if not found.", NULL},
12377     {"state_name", (getter)DN_get_state_name, (setter)NULL,
12378      "Returns the state name member (i.e. ST) as a string. Returns None if not found.", NULL},
12379     {"org_name", (getter)DN_get_org_name, (setter)NULL,
12380      "Returns the organization name member (i.e. O) as a string. Returns None if not found.", NULL},
12381     {"org_unit_name", (getter)DN_get_org_unit_name, (setter)NULL,
12382      "Returns the organizational unit name member (i.e. OU) as a string. Returns None if not found.", NULL},
12383     {"dc_name", (getter)DN_get_domain_component_name, (setter)NULL,
12384      "Returns the domain component name member (i.e. DC) as a string. Returns None if not found.", NULL},
12385     {"cert_uid", (getter)DN_get_cert_uid, (setter)NULL,
12386      "Returns the certificate uid member (i.e. UID) as a string. Returns None if not found.", NULL},
12387     {NULL}  /* Sentinel */
12388 };
12389 
12390 static PyMemberDef DN_members[] = {
12391     {NULL}  /* Sentinel */
12392 };
12393 
12394 /* ============================== Class Methods ============================= */
12395 
12396 static PyObject *
DN_richcompare(DN * self,DN * other,int op)12397 DN_richcompare(DN *self, DN *other, int op)
12398 {
12399     int cmp_result;
12400 
12401     if (!PyDN_Check(other)) {
12402         PyErr_SetString(PyExc_TypeError, "Bad type, must be DN");
12403         return NULL;
12404     }
12405 
12406     cmp_result = CERT_CompareName(&self->name, &other->name);
12407     RETURN_COMPARE_RESULT(op, cmp_result)
12408 
12409 }
12410 
12411 PyDoc_STRVAR(DN_add_rdn_doc,
12412 "add_rdn(rdn) \n\
12413 \n\
12414 :Parameters:\n\
12415     rdn : RDN object\n\
12416         The rnd to add to the name\n\
12417 \n\
12418 Adds a RDN to the name.\n\
12419 ");
12420 
12421 static PyObject *
DN_add_rdn(DN * self,PyObject * args)12422 DN_add_rdn(DN *self, PyObject *args)
12423 {
12424     RDN *py_rdn;
12425 
12426     TraceMethodEnter(self);
12427 
12428     if (!PyArg_ParseTuple(args, "O!:add_rdn",
12429                           &RDNType, &py_rdn))
12430         return NULL;
12431 
12432     if (CERT_AddRDN(&self->name, py_rdn->rdn) != SECSuccess) {
12433         return set_nspr_error(NULL);
12434     }
12435 
12436     Py_RETURN_NONE;
12437 }
12438 
12439 static PyMethodDef DN_methods[] = {
12440     {"has_key", (PyCFunction)DN_has_key, METH_VARARGS, DN_has_key_doc},
12441     {"add_rdn", (PyCFunction)DN_add_rdn, METH_VARARGS, DN_add_rdn_doc},
12442     {NULL, NULL}  /* Sentinel */
12443 };
12444 
12445 /* =========================== Class Construction =========================== */
12446 
12447 static PyObject *
DN_new(PyTypeObject * type,PyObject * args,PyObject * kwds)12448 DN_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
12449 {
12450     DN *self;
12451 
12452     TraceObjNewEnter(type);
12453 
12454     if ((self = (DN *)type->tp_alloc(type, 0)) == NULL) {
12455         return NULL;
12456     }
12457 
12458     if ((self->arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE)) == NULL) {
12459         type->tp_free(self);
12460         return set_nspr_error(NULL);
12461     }
12462 
12463     memset(&self->name, 0, sizeof(self->name));
12464 
12465     TraceObjNewLeave(self);
12466     return (PyObject *)self;
12467 }
12468 
12469 static void
DN_dealloc(DN * self)12470 DN_dealloc(DN* self)
12471 {
12472     TraceMethodEnter(self);
12473 
12474     CERT_DestroyName(&self->name);
12475 
12476     if (self->arena) {
12477         PORT_FreeArena(self->arena, PR_FALSE);
12478     }
12479 
12480     Py_TYPE(self)->tp_free((PyObject*)self);
12481 }
12482 
12483 PyDoc_STRVAR(DN_doc,
12484 "An object representing an X501 Distinguished Name (e.g DN).\n\
12485 \n\
12486 DN objects contain an ordered list of `RDN` objects.\n\
12487 \n\
12488 The DN object constructor may be invoked with a string\n\
12489 representing an X500 name. Zero or more `RDN` objects, or you may\n\
12490 optionally pass a list or tuple of `RDN` objects.\n\
12491 \n\
12492 Examples::\n\
12493 \n\
12494     DN()\n\
12495     DN('CN=www.redhat.com,OU=Web Operations,O=Red Hat Inc,L=Raleigh,ST=North Carolina,C=US')\n\
12496     DN(rdn0, ...)\n\
12497     DN([rdn0, rdn1])\n\
12498 \n\
12499 **The string representation of a Distinguished Name (DN) has reverse\n\
12500 ordering from it's sequential components.**\n\
12501 \n\
12502 The ordering is a requirement of the relevant RFC's. When a\n\
12503 Distinguished Name is rendered as a string it is ordered from most\n\
12504 specific to least specific. However it's components (RDN's) as a\n\
12505 sequence are ordered from least specific to most specific.\n\
12506 \n\
12507 DN objects contain an ordered list of `RDN` objects. The\n\
12508 DN object has both sequence and mapping behaviors with respect to\n\
12509 the RDN's they contain. Thus you can index an RDN by position, by\n\
12510 name, or by SecItem (if it's an OID). You can iterate over the list,\n\
12511 get it's length or take a slice.\n\
12512 \n\
12513 If you index by string the string may be either a canonical name for\n\
12514 the RDN type (e.g. 'cn') or the dotted-decimal notation for the OID\n\
12515 (e.g. 2.5.4.3). There may be multiple RDN's in a DN whose type matches\n\
12516 (e.g. OU=engineering, OU=boston). It is not common to have more than\n\
12517 one RDN in a DN with the same type. However because of the possiblity\n\
12518 of being multi-valued when indexing by type a list is always returned\n\
12519 containing the matching RDN's. Thus::\n\
12520 \n\
12521     dn = nss.DN('OU=engineering')\n\
12522     dn['ou']\n\
12523         returns [RDN('OU=engineering')\n\
12524 \n\
12525     dn = nss.DN('OU=engineering, OU=boston')\n\
12526     dn['ou']\n\
12527         returns [RDN('OU=boston'), RDN('OU=engineering')]\n\
12528         Note the reverse ordering between string representation and RDN sequencing\n\
12529 \n\
12530 Note, if you use properties to access the RDN values (e.g. name.common_name,\n\
12531 name.org_unit_name) the string value is returned or None if not found.\n\
12532 If the item was multi-valued then the most appropriate item will be selected\n\
12533 and returned as a string value.\n\
12534 \n\
12535 Note it is not possible to index by oid tag\n\
12536 (e.g. nss.SEC_OID_AVA_COMMON_NAME) because oid tags are integers and\n\
12537 it's impossible to distinguish between an integer representing the\n\
12538 n'th member of the sequence and the integer representing the oid\n\
12539 tag. In this case positional indexing wins (e.g. rdn[0] means the\n\
12540 first element).\n\
12541 \n\
12542 Examples::\n\
12543 \n\
12544     subject_name = 'CN=www.redhat.com,OU=Web Operations,O=Red Hat Inc,L=Raleigh,ST=North Carolina,C=US'\n\
12545     name = nss.DN(subject_name)\n\
12546     str(name)\n\
12547        returns 'CN=www.redhat.com,OU=Web Operations,O=Red Hat Inc,L=Raleigh,ST=North Carolina,C=US'\n\
12548     name[0]\n\
12549        returns an `RDN` object with the value C=US\n\
12550     name['cn']\n\
12551         returns a list comprised of an `RDN` object with the value CN=www.redhat.com\n\
12552     name['2.5.4.3']\n\
12553         returns a list comprised of an `RDN` object with the value CN=www.redhat.com\n\
12554         because 2.5.4.3 is the dotted-decimal OID for common name (i.e. cn)\n\
12555     name.common_name\n\
12556         returns the string www.redhat.com\n\
12557         common_name is easy shorthand property, it only retuns a single string\n\
12558         value or None, if it was multi-valued the most appropriate item is selected.\n\
12559     name.has_key('cn')\n\
12560         returns True because the DN has a common name RDN\n\
12561     name.has_key('2.5.4.3')\n\
12562         returns True because the DN has a common name RDN\n\
12563         because 2.5.4.3 is the dotted-decimal OID for common name (i.e. cn)\n\
12564 \n\
12565     cn_rdn = nss.RDN(nss.AVA('cn', 'www.redhat.com'))\n\
12566     ou_rdn = nss.RDN(nss.AVA('ou', 'Web Operations'))\n\
12567     name = nss.DN(cn_rdn)\n\
12568     name\n\
12569        is a DN with one RDN (e.g. CN=www.redhat.com)\n\
12570     len(name)\n\
12571        returns 1 because there is one RDN in it\n\
12572     name.add_rdn(ou_rdn)\n\
12573     name\n\
12574        name is now a DN with two RDN's (e.g. OU=Web Operations,CN=www.redhat.com)\n\
12575     len(name)\n\
12576        returns 2 because there are now two RDN's in it\n\
12577     list(name)\n\
12578        returns a list with the two RDN's in it\n\
12579     name[:]\n\
12580        same as list(name)\n\
12581     for rdn in name:\n\
12582        iterate over each RDN in name\n\
12583     name = nss.DN(cn_rdn, ou_rdn)\n\
12584         This is an alternate way to build the above DN\n\
12585 ");
12586 
12587 static int
DN_init(DN * self,PyObject * args,PyObject * kwds)12588 DN_init(DN *self, PyObject *args, PyObject *kwds)
12589 {
12590     PyObject *sequence, *item;
12591     Py_ssize_t sequence_len, i;
12592     RDN *py_rdn;
12593     CERTRDN *new_rdn;
12594     CERTName *cert_name;
12595     CERTRDN *rdn_arg[MAX_RDNS+1];  /* +1 for NULL terminator */
12596 
12597     TraceMethodEnter(self);
12598 
12599     CERT_DestroyName(&self->name);
12600 
12601     if (PyTuple_GET_SIZE(args) > 0) {
12602         item = PyTuple_GetItem(args, 0);
12603         if (PyBaseString_Check(item)) {
12604             PyObject *name_utf8 = NULL;
12605             char *ascii_name;
12606 
12607             if ((name_utf8 = PyBaseString_UTF8(item, "DN name")) == NULL) {
12608                 return -1;
12609             }
12610             ascii_name = PyBytes_AS_STRING(name_utf8);
12611 
12612             if (strlen(ascii_name) == 0) goto empty_name;
12613 
12614             if ((cert_name = CERT_AsciiToName(ascii_name)) == NULL) {
12615                 set_nspr_error("cannot parse X500 name \"%s\"", ascii_name);
12616                 Py_DECREF(name_utf8);
12617                 return -1;
12618             }
12619 
12620             self->name = *cert_name;
12621             Py_DECREF(name_utf8);
12622             return 0;
12623         }
12624 
12625         if (PyRDN_Check(item)) {
12626             sequence = args;
12627         } else if (PyList_Check(item) || PyTuple_Check(item)) {
12628             sequence = item;
12629         } else {
12630             PyErr_Format(PyExc_TypeError, "must be an RDN object or list or tuple of RDN objects, not %.200s",
12631                          Py_TYPE(item)->tp_name);
12632             return -1;
12633         }
12634 
12635         sequence_len = PySequence_Length(sequence);
12636 
12637         if (sequence_len > MAX_RDNS) {
12638             PyErr_Format(PyExc_ValueError, "to many RDN items, maximum is %d, received %zd",
12639                          MAX_RDNS-1, sequence_len);
12640             return -1;
12641         }
12642 
12643         for (i = 0; i < sequence_len && i < MAX_RDNS; i++) {
12644             item = PySequence_ITEM(sequence, i);
12645             if (PyRDN_Check(item)) {
12646                 py_rdn = (RDN *)item;
12647 
12648                 if ((new_rdn = CERT_CreateRDN(self->arena, NULL)) == NULL) {
12649                     set_nspr_error(NULL);
12650                     Py_DECREF(item);
12651                     return -1;
12652                 }
12653 
12654                 if (CERT_CopyRDN(self->arena, new_rdn, py_rdn->rdn) != SECSuccess) {
12655                     set_nspr_error(NULL);
12656                     Py_DECREF(item);
12657                     return -1;
12658                 }
12659                 rdn_arg[i] = new_rdn;
12660             } else {
12661                 PyErr_Format(PyExc_TypeError, "item %zd must be an RDN object, not %.200s",
12662                              i, Py_TYPE(item)->tp_name);
12663                 Py_DECREF(item);
12664                 return -1;
12665             }
12666             Py_DECREF(item);
12667         }
12668 
12669         for (; i < MAX_RDNS+1; i++) rdn_arg[i] = NULL;
12670 
12671         if ((cert_name = CERT_CreateName(rdn_arg[0], rdn_arg[1], rdn_arg[2], rdn_arg[3],
12672                                          rdn_arg[4], rdn_arg[5], rdn_arg[6], rdn_arg[7],
12673                                          rdn_arg[8], rdn_arg[9], rdn_arg[10])) == NULL) {
12674             set_nspr_error(NULL);
12675             return -1;
12676         }
12677         self->name = *cert_name;
12678     } else {
12679     empty_name:
12680         if ((cert_name = CERT_CreateName(NULL)) == NULL) {
12681             set_nspr_error(NULL);
12682             return -1;
12683         }
12684         self->name = *cert_name;
12685     }
12686     return 0;
12687 }
12688 
12689 static PyObject *
DN_repr(DN * self)12690 DN_repr(DN *self)
12691 {
12692     return CERTName_to_pystr(&self->name);
12693 }
12694 
12695 static PySequenceMethods DN_as_sequence = {
12696     (lenfunc)DN_length,				/* sq_length */
12697     0,						/* sq_concat */
12698     0,						/* sq_repeat */
12699     (ssizeargfunc)DN_item,			/* sq_item */
12700     0,						/* sq_slice */
12701     0,						/* sq_ass_item */
12702     0,						/* sq_ass_slice */
12703     (objobjproc)DN_contains,			/* sq_contains */
12704     0,						/* sq_inplace_concat */
12705     0,						/* sq_inplace_repeat */
12706 };
12707 
12708 static PyMappingMethods DN_as_mapping = {
12709     (lenfunc)DN_length,				/* mp_length */
12710     (binaryfunc)DN_subscript,			/* mp_subscript */
12711     0,						/* mp_ass_subscript */
12712 };
12713 
12714 static PyTypeObject DNType = {
12715     PyVarObject_HEAD_INIT(NULL, 0)
12716     "nss.nss.DN",				/* tp_name */
12717     sizeof(DN),					/* tp_basicsize */
12718     0,						/* tp_itemsize */
12719     (destructor)DN_dealloc,			/* tp_dealloc */
12720     0,						/* tp_print */
12721     0,						/* tp_getattr */
12722     0,						/* tp_setattr */
12723     0,						/* tp_compare */
12724     (reprfunc)DN_repr,				/* tp_repr */
12725     0,						/* tp_as_number */
12726     &DN_as_sequence,				/* tp_as_sequence */
12727     &DN_as_mapping,				/* tp_as_mapping */
12728     0,						/* tp_hash */
12729     0,						/* tp_call */
12730     0,						/* tp_str */
12731     0,						/* tp_getattro */
12732     0,						/* tp_setattro */
12733     0,						/* tp_as_buffer */
12734     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,	/* tp_flags */
12735     DN_doc,					/* tp_doc */
12736     0,						/* tp_traverse */
12737     0,						/* tp_clear */
12738     (richcmpfunc)DN_richcompare,		/* tp_richcompare */
12739     0,						/* tp_weaklistoffset */
12740     0,						/* tp_iter */
12741     0,						/* tp_iternext */
12742     DN_methods,					/* tp_methods */
12743     DN_members,					/* tp_members */
12744     DN_getseters,				/* tp_getset */
12745     0,						/* tp_base */
12746     0,						/* tp_dict */
12747     0,						/* tp_descr_get */
12748     0,						/* tp_descr_set */
12749     0,						/* tp_dictoffset */
12750     (initproc)DN_init,				/* tp_init */
12751     0,						/* tp_alloc */
12752     DN_new,					/* tp_new */
12753 };
12754 
12755 PyObject *
DN_new_from_CERTName(CERTName * name)12756 DN_new_from_CERTName(CERTName *name)
12757 {
12758     DN *self = NULL;
12759     PRArenaPool *arena;
12760 
12761     TraceObjNewEnter(NULL);
12762 
12763     if ((self = (DN *) DNType.tp_new(&DNType, NULL, NULL)) == NULL) {
12764         return NULL;
12765     }
12766 
12767     if ((arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE)) == NULL) {
12768         set_nspr_error(NULL);
12769         Py_CLEAR(self);
12770         return NULL;
12771     }
12772 
12773     if (CERT_CopyName(arena, &self->name, name) != SECSuccess) {
12774         set_nspr_error(NULL);
12775         Py_CLEAR(self);
12776         return NULL;
12777     }
12778 
12779     TraceObjNewLeave(self);
12780     return (PyObject *) self;
12781 }
12782 
12783 /* ========================================================================== */
12784 /* =========================== GeneralName Class ============================ */
12785 /* ========================================================================== */
12786 
12787 /* ============================ Attribute Access ============================ */
12788 
12789 static PyObject *
GeneralName_get_name_string(GeneralName * self,void * closure)12790 GeneralName_get_name_string(GeneralName *self, void *closure)
12791 {
12792     TraceMethodEnter(self);
12793 
12794     if (!self->name) {
12795         return PyErr_Format(PyExc_ValueError, "%s is uninitialized", Py_TYPE(self)->tp_name);
12796     }
12797     return CERTGeneralName_to_pystr(self->name);
12798 }
12799 
12800 static PyObject *
GeneralName_get_type_enum(GeneralName * self,void * closure)12801 GeneralName_get_type_enum(GeneralName *self, void *closure)
12802 {
12803     TraceMethodEnter(self);
12804 
12805     if (!self->name) {
12806         return PyErr_Format(PyExc_ValueError, "%s is uninitialized", Py_TYPE(self)->tp_name);
12807     }
12808     return PyLong_FromLong(self->name->type);
12809 }
12810 
12811 static PyObject *
GeneralName_get_type_name(GeneralName * self,void * closure)12812 GeneralName_get_type_name(GeneralName *self, void *closure)
12813 {
12814     TraceMethodEnter(self);
12815 
12816     if (!self->name) {
12817         return PyErr_Format(PyExc_ValueError, "%s is uninitialized", Py_TYPE(self)->tp_name);
12818     }
12819     return general_name_type_to_pystr(self->name->type);
12820 }
12821 
12822 static PyObject *
GeneralName_get_type_string(GeneralName * self,void * closure)12823 GeneralName_get_type_string(GeneralName *self, void *closure)
12824 {
12825     TraceMethodEnter(self);
12826 
12827     if (!self->name) {
12828         return PyErr_Format(PyExc_ValueError, "%s is uninitialized", Py_TYPE(self)->tp_name);
12829     }
12830     return CERTGeneralName_type_string_to_pystr(self->name);
12831 }
12832 
12833 static
12834 PyGetSetDef GeneralName_getseters[] = {
12835     {"name",      (getter)GeneralName_get_name_string, (setter)NULL,
12836      "Returns the general name as a string", NULL},
12837     {"type_enum", (getter)GeneralName_get_type_enum, (setter)NULL,
12838      "Returns the general name type enumerated constant", NULL},
12839     {"type_name", (getter)GeneralName_get_type_name, (setter)NULL,
12840      "Returns the general name type enumerated constant as a string", NULL},
12841     {"type_string", (getter)GeneralName_get_type_string, (setter)NULL,
12842      "Returns the type of the general name as a string (e.g. \"URI\")", NULL},
12843     {NULL}  /* Sentinel */
12844 };
12845 
12846 static PyMemberDef GeneralName_members[] = {
12847     {NULL}  /* Sentinel */
12848 };
12849 
12850 /* ============================== Class Methods ============================= */
12851 
12852 PyDoc_STRVAR(GeneralName_get_name_doc,
12853 "get_name(repr_kind=AsString) -> \n\
12854 \n\
12855 :Parameters:\n\
12856     repr_kind : RepresentationKind constant\n\
12857         Specifies what the contents of the returned tuple will be.\n\
12858         May be one of:\n\
12859 \n\
12860         AsObject\n\
12861             The general name as a nss.GeneralName object\n\
12862         AsString\n\
12863             The general name as a string.\n\
12864             (e.g. \"http://crl.geotrust.com/crls/secureca.crl\")\n\
12865         AsTypeString\n\
12866             The general name type as a string.\n\
12867              (e.g. \"URI\")\n\
12868         AsTypeEnum\n\
12869             The general name type as a general name type enumerated constant.\n\
12870              (e.g. nss.certURI )\n\
12871         AsLabeledString\n\
12872             The general name as a string with it's type prepended.\n\
12873             (e.g. \"URI: http://crl.geotrust.com/crls/secureca.crl\"\n\
12874 \n\
12875 Returns the value of the GeneralName according to the representation type parameter.\n\
12876 ");
12877 
12878 static PyObject *
GeneralName_get_name(GeneralName * self,PyObject * args,PyObject * kwds)12879 GeneralName_get_name(GeneralName *self, PyObject *args, PyObject *kwds)
12880 {
12881     static char *kwlist[] = {"repr_kind", NULL};
12882     PyObject *name;
12883     int repr_kind = AsString;
12884 
12885     TraceMethodEnter(self);
12886 
12887     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|i:get_name", kwlist,
12888                                      &repr_kind))
12889         return NULL;
12890 
12891 
12892     if (!self->name) {
12893         return PyErr_Format(PyExc_ValueError, "%s is uninitialized", Py_TYPE(self)->tp_name);
12894     }
12895 
12896     switch(repr_kind) {
12897     case AsObject:
12898         Py_INCREF(self);
12899         name = (PyObject *)self;
12900         break;
12901     case AsString:
12902         name = CERTGeneralName_to_pystr(self->name);
12903         break;
12904     case AsTypeString:
12905         name = CERTGeneralName_type_string_to_pystr(self->name);
12906         break;
12907     case AsTypeEnum:
12908         name = PyLong_FromLong(self->name->type);
12909         break;
12910     case AsLabeledString:
12911         name = CERTGeneralName_to_pystr_with_label(self->name);
12912         break;
12913     default:
12914         PyErr_Format(PyExc_ValueError, "Unsupported representation kind (%d)", repr_kind);
12915         return NULL;
12916     }
12917 
12918     return name;
12919 }
12920 
12921 static PyMethodDef GeneralName_methods[] = {
12922     {"get_name", (PyCFunction)GeneralName_get_name, METH_VARARGS|METH_KEYWORDS, GeneralName_get_name_doc},
12923     {NULL, NULL}  /* Sentinel */
12924 };
12925 
12926 /* =========================== Class Construction =========================== */
12927 
12928 static PyObject *
GeneralName_new(PyTypeObject * type,PyObject * args,PyObject * kwds)12929 GeneralName_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
12930 {
12931     GeneralName *self;
12932 
12933     TraceObjNewEnter(type);
12934 
12935     if ((self = (GeneralName *)type->tp_alloc(type, 0)) == NULL) {
12936         return NULL;
12937     }
12938 
12939     if ((self->arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE)) == NULL) {
12940         type->tp_free(self);
12941         return set_nspr_error(NULL);
12942     }
12943 
12944     self->name = NULL;
12945 
12946     TraceObjNewLeave(self);
12947     return (PyObject *)self;
12948 }
12949 
12950 static void
GeneralName_dealloc(GeneralName * self)12951 GeneralName_dealloc(GeneralName* self)
12952 {
12953     TraceMethodEnter(self);
12954 
12955     if (self->arena) {
12956         PORT_FreeArena(self->arena, PR_FALSE);
12957     }
12958 
12959     Py_TYPE(self)->tp_free((PyObject*)self);
12960 }
12961 
12962 PyDoc_STRVAR(GeneralName_doc,
12963 "An object representing a GeneralName or list of GeneralNames.\n\
12964 \n\
12965 ");
12966 
12967 static int
GeneralName_init(GeneralName * self,PyObject * args,PyObject * kwds)12968 GeneralName_init(GeneralName *self, PyObject *args, PyObject *kwds)
12969 {
12970     static char *kwlist[] = {"sec_item", NULL};
12971     SecItem *py_sec_item;
12972 
12973     TraceMethodEnter(self);
12974 
12975     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!:GeneralName", kwlist,
12976                                      &SecItemType, &py_sec_item))
12977         return -1;
12978 
12979     if ((self->name = CERT_DecodeGeneralName(self->arena, &py_sec_item->item, NULL)) == NULL) {
12980         set_nspr_error(NULL);
12981         return -1;
12982     }
12983 
12984     return 0;
12985 }
12986 
12987 static PyObject *
GeneralName_repr(GeneralName * self)12988 GeneralName_repr(GeneralName *self)
12989 {
12990     PyObject *result = NULL;
12991 
12992     if (!self->name) {
12993         return PyErr_Format(PyExc_ValueError, "%s is uninitialized", Py_TYPE(self)->tp_name);
12994     }
12995 
12996     if ((result = CERTGeneralName_to_pystr_with_label(self->name)) == NULL) {
12997         result = PyUnicode_FromFormat("<%s object at %p>",
12998                                      Py_TYPE(self)->tp_name, self);
12999     }
13000 
13001     return result;
13002 }
13003 
13004 static Py_ssize_t
GeneralName_length(GeneralName * self)13005 GeneralName_length(GeneralName *self)
13006 {
13007     if (!self->name) {
13008         PyErr_Format(PyExc_ValueError, "%s is uninitialized", Py_TYPE(self)->tp_name);
13009         return -1;
13010     }
13011 
13012     return CERTGeneralName_list_count(self->name);
13013 }
13014 
13015 static PyObject *
GeneralName_item(GeneralName * self,register Py_ssize_t i)13016 GeneralName_item(GeneralName *self, register Py_ssize_t i)
13017 {
13018     CERTGeneralName *head, *cur;
13019     Py_ssize_t index;
13020 
13021     if (!self->name) {
13022         return PyErr_Format(PyExc_ValueError, "%s is uninitialized", Py_TYPE(self)->tp_name);
13023     }
13024 
13025     index = 0;
13026     cur = head = self->name;
13027     do {
13028         cur = CERT_GetNextGeneralName(cur);
13029         if (i == index) {
13030             return GeneralName_new_from_CERTGeneralName(cur);
13031         }
13032         index++;
13033     } while (cur != head);
13034 
13035     PyErr_SetString(PyExc_IndexError, "GeneralName index out of range");
13036     return NULL;
13037 }
13038 
13039 static PySequenceMethods GeneralName_as_sequence = {
13040     (lenfunc)GeneralName_length,		/* sq_length */
13041     0,						/* sq_concat */
13042     0,						/* sq_repeat */
13043     (ssizeargfunc)GeneralName_item,		/* sq_item */
13044     0,						/* sq_slice */
13045     0,						/* sq_ass_item */
13046     0,						/* sq_ass_slice */
13047     0,						/* sq_contains */
13048     0,						/* sq_inplace_concat */
13049     0,						/* sq_inplace_repeat */
13050 };
13051 
13052 static PyTypeObject GeneralNameType = {
13053     PyVarObject_HEAD_INIT(NULL, 0)
13054     "nss.nss.GeneralName",			/* tp_name */
13055     sizeof(GeneralName),			/* tp_basicsize */
13056     0,						/* tp_itemsize */
13057     (destructor)GeneralName_dealloc,		/* tp_dealloc */
13058     0,						/* tp_print */
13059     0,						/* tp_getattr */
13060     0,						/* tp_setattr */
13061     0,						/* tp_compare */
13062     (reprfunc)GeneralName_repr,			/* tp_repr */
13063     0,						/* tp_as_number */
13064     &GeneralName_as_sequence,			/* tp_as_sequence */
13065     0,						/* tp_as_mapping */
13066     0,						/* tp_hash */
13067     0,						/* tp_call */
13068     0,						/* tp_str */
13069     0,						/* tp_getattro */
13070     0,						/* tp_setattro */
13071     0,						/* tp_as_buffer */
13072     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,	/* tp_flags */
13073     GeneralName_doc,				/* tp_doc */
13074     0,						/* tp_traverse */
13075     0,						/* tp_clear */
13076     0,						/* tp_richcompare */
13077     0,						/* tp_weaklistoffset */
13078     0,						/* tp_iter */
13079     0,						/* tp_iternext */
13080     GeneralName_methods,			/* tp_methods */
13081     GeneralName_members,			/* tp_members */
13082     GeneralName_getseters,			/* tp_getset */
13083     0,						/* tp_base */
13084     0,						/* tp_dict */
13085     0,						/* tp_descr_get */
13086     0,						/* tp_descr_set */
13087     0,						/* tp_dictoffset */
13088     (initproc)GeneralName_init,			/* tp_init */
13089     0,						/* tp_alloc */
13090     0,						/* tp_new */
13091 };
13092 
13093 PyObject *
GeneralName_new_from_CERTGeneralName(CERTGeneralName * name)13094 GeneralName_new_from_CERTGeneralName(CERTGeneralName *name)
13095 {
13096     GeneralName *self = NULL;
13097 
13098     TraceObjNewEnter(NULL);
13099 
13100     if ((self = (GeneralName *) GeneralName_new(&GeneralNameType, NULL, NULL)) == NULL) {
13101         return NULL;
13102     }
13103 
13104     /*
13105      * NSS WART
13106      * There is no public API to create a CERTGeneralName, copy it, or free it.
13107      * You don't know what arena was used to create the general name.
13108      * GeneralNames are linked in a list, this makes it difficult for a
13109      * general name to exist independently, it would have been better if there
13110      * was a list container independent general names could be placed in,
13111      * then you wouldn't have to worry about the link fields in each independent name.
13112      */
13113 
13114     if (CERT_CopyGeneralName(self->arena, &self->name, name) != SECSuccess) {
13115         set_nspr_error(NULL);
13116         Py_CLEAR(self);
13117         return NULL;
13118     }
13119 
13120     TraceObjNewLeave(self);
13121     return (PyObject *) self;
13122 }
13123 
13124 PyDoc_STRVAR(cert_get_default_certdb_doc,
13125 "get_default_certdb()\n\
13126 \n\
13127 Returns the default certificate database as a CertDB object\n\
13128 ");
13129 static PyObject *
cert_get_default_certdb(PyObject * self,PyObject * args)13130 cert_get_default_certdb(PyObject *self, PyObject *args)
13131 {
13132     CERTCertDBHandle *certdb_handle;
13133 
13134     TraceMethodEnter(self);
13135 
13136     if ((certdb_handle = CERT_GetDefaultCertDB()) == NULL) {
13137         Py_RETURN_NONE;
13138     }
13139 
13140     return CertDB_new_from_CERTCertDBHandle(certdb_handle);
13141 }
13142 
13143 PyDoc_STRVAR(cert_get_cert_nicknames_doc,
13144 "get_cert_nicknames(certdb, what, [user_data1, ...]) -> name0, ...\n\
13145 \n\
13146 :Parameters:\n\
13147     certdb : CertDB object\n\
13148         CertDB certificate database object\n\
13149     what : integer\n\
13150         one of:\n\
13151             - SEC_CERT_NICKNAMES_ALL\n\
13152             - SEC_CERT_NICKNAMES_USER\n\
13153             - SEC_CERT_NICKNAMES_SERVER\n\
13154             - SEC_CERT_NICKNAMES_CA\n\
13155     user_dataN : object\n\
13156         zero or more caller supplied parameters which will\n\
13157         be passed to the password callback function\n\
13158 \n\
13159 Returns a tuple of the nicknames of the certificates in a specified\n\
13160 certificate database.\n\
13161 ");
13162 
13163 static PyObject *
cert_get_cert_nicknames(PyObject * self,PyObject * args)13164 cert_get_cert_nicknames(PyObject *self, PyObject *args)
13165 {
13166     Py_ssize_t n_base_args = 2;
13167     Py_ssize_t argc;
13168     PyObject *parse_args = NULL;
13169     PyObject *pin_args = NULL;
13170     CertDB *py_certdb = NULL;
13171     int what;
13172     CERTCertNicknames *cert_nicknames = NULL;
13173     PyObject *py_nicknames = NULL;
13174     PyObject *py_nickname = NULL;
13175     int i, len;
13176 
13177     TraceMethodEnter(self);
13178 
13179     argc = PyTuple_Size(args);
13180     if (argc == n_base_args) {
13181         Py_INCREF(args);
13182         parse_args = args;
13183     } else {
13184         parse_args = PyTuple_GetSlice(args, 0, n_base_args);
13185     }
13186     if (!PyArg_ParseTuple(parse_args, "O!i:get_cert_nicknames",
13187                           &CertDBType, &py_certdb, &what)) {
13188         Py_DECREF(parse_args);
13189         return NULL;
13190     }
13191     Py_DECREF(parse_args);
13192 
13193     pin_args = PyTuple_GetSlice(args, n_base_args, argc);
13194 
13195     Py_BEGIN_ALLOW_THREADS
13196     if ((cert_nicknames = CERT_GetCertNicknames(py_certdb->handle, what, pin_args)) == NULL) {
13197 	Py_BLOCK_THREADS
13198         Py_DECREF(pin_args);
13199         return set_nspr_error(NULL);
13200     }
13201     Py_END_ALLOW_THREADS
13202 
13203     Py_DECREF(pin_args);
13204 
13205     len = cert_nicknames->numnicknames;
13206     if ((py_nicknames = PyTuple_New(len)) == NULL) {
13207         CERT_FreeNicknames(cert_nicknames);
13208         return NULL;
13209     }
13210 
13211     for (i = 0; i < len; i++) {
13212         if ((py_nickname = PyUnicode_FromString(cert_nicknames->nicknames[i])) == NULL) {
13213             CERT_FreeNicknames(cert_nicknames);
13214             return NULL;
13215         }
13216         PyTuple_SetItem(py_nicknames, i, py_nickname);
13217     }
13218 
13219     CERT_FreeNicknames(cert_nicknames);
13220 
13221     return py_nicknames;
13222 }
13223 
13224 PyDoc_STRVAR(pk11_hash_buf_doc,
13225 "hash_buf(hash_alg, data) --> digest\n\
13226 \n\
13227 :Parameters:\n\
13228     hash_alg : int\n\
13229         hash algorithm enumeration (SEC_OID_*)\n\
13230         e.g.: SEC_OID_MD5, SEC_OID_SHA1, SEC_OID_SHA256, SEC_OID_SHA512, etc.\n\
13231     data : buffer or string\n\
13232         buffer the digest will be computed for\n\
13233 \n\
13234 Computes a digest according to the hash_alg type.\n\
13235 Return the digest data as buffer object.\n\
13236 \n\
13237 Note, if a hexidecimal string representation is desired then pass\n\
13238 result to data_to_hex()\n\
13239 ");
13240 static PyObject *
pk11_hash_buf(PyObject * self,PyObject * args)13241 pk11_hash_buf(PyObject *self, PyObject *args)
13242 {
13243     unsigned long hash_alg;
13244     unsigned char *in_data = NULL;
13245     Py_ssize_t in_data_len = 0;
13246     unsigned int hash_len;
13247     PyObject *py_out_buf = NULL;
13248     void *out_buf = NULL;
13249     Py_ssize_t out_buf_len;
13250 
13251     TraceMethodEnter(self);
13252 
13253 #if PY_MAJOR_VERSION >= 3
13254     /* Py2 -> Py3 difference is t# -> y# */
13255     if (!PyArg_ParseTuple(args, "ky#:hash_buf",
13256                           &hash_alg, &in_data, &in_data_len))
13257         return NULL;
13258 #else
13259     if (!PyArg_ParseTuple(args, "kt#:hash_buf",
13260                           &hash_alg, &in_data, &in_data_len))
13261         return NULL;
13262 #endif
13263 
13264     if ((hash_len = HASH_ResultLenByOidTag(hash_alg)) == 0) {
13265         return set_nspr_error("unable to determine resulting hash length for hash_alg = %s",
13266                               oid_tag_str(hash_alg));
13267     }
13268 
13269     out_buf_len = hash_len;
13270 
13271     if ((py_out_buf = PyBytes_FromStringAndSize(NULL, out_buf_len)) == NULL) {
13272         return NULL;
13273     }
13274 
13275     if ((out_buf = PyBytes_AsString(py_out_buf)) == NULL) {
13276         return NULL;
13277     }
13278 
13279     if (PK11_HashBuf(hash_alg, out_buf, in_data, in_data_len) != SECSuccess) {
13280         return set_nspr_error(NULL);
13281     }
13282 
13283     return py_out_buf;
13284 }
13285 
13286 PyDoc_STRVAR(pk11_md5_digest_doc,
13287 "md5_digest(data) --> digest\n\
13288 \n\
13289 :Parameters:\n\
13290     data : buffer or string\n\
13291         buffer the digest will be computed for\n\
13292 \n\
13293 Returns 16 octet MD5 digest data as buffer object.\n\
13294 \n\
13295 Note, if a hexidecimal string representation is desired then pass\n\
13296 result to data_to_hex()\n\
13297 ");
13298 static PyObject *
pk11_md5_digest(PyObject * self,PyObject * args)13299 pk11_md5_digest(PyObject *self, PyObject *args)
13300 {
13301     unsigned char *in_data = NULL;
13302     Py_ssize_t in_data_len = 0;
13303     PyObject *py_out_buf = NULL;
13304     void *out_buf;
13305 
13306     TraceMethodEnter(self);
13307 
13308 #if PY_MAJOR_VERSION >= 3
13309     /* Py2 -> Py3 difference is t# -> y# */
13310     if (!PyArg_ParseTuple(args, "y#:md5_digest", &in_data, &in_data_len))
13311         return NULL;
13312 #else
13313     if (!PyArg_ParseTuple(args, "t#:md5_digest", &in_data, &in_data_len))
13314         return NULL;
13315 #endif
13316 
13317     if ((py_out_buf = PyBytes_FromStringAndSize(NULL, MD5_LENGTH)) == NULL) {
13318         return NULL;
13319     }
13320 
13321     if ((out_buf = PyBytes_AsString(py_out_buf)) == NULL) {
13322         return NULL;
13323     }
13324 
13325     if (PK11_HashBuf(SEC_OID_MD5, out_buf, in_data, in_data_len) != SECSuccess) {
13326         return set_nspr_error(NULL);
13327     }
13328 
13329     return py_out_buf;
13330 }
13331 
13332 PyDoc_STRVAR(pk11_sha1_digest_doc,
13333 "sha1_digest(data) --> digest\n\
13334 \n\
13335 :Parameters:\n\
13336     data : buffer or string\n\
13337         buffer the digest will be computed for\n\
13338 \n\
13339 Returns 20 octet SHA1 digest data as buffer object.\n\
13340 \n\
13341 Note, if a hexidecimal string representation is desired then pass\n\
13342 result to data_to_hex()\n\
13343 ");
13344 static PyObject *
pk11_sha1_digest(PyObject * self,PyObject * args)13345 pk11_sha1_digest(PyObject *self, PyObject *args)
13346 {
13347     unsigned char *in_data = NULL;
13348     Py_ssize_t in_data_len = 0;
13349     PyObject *py_out_buf = NULL;
13350     void *out_buf;
13351 
13352     TraceMethodEnter(self);
13353 
13354 #if PY_MAJOR_VERSION >= 3
13355     /* Py2 -> Py3 difference is t# -> y# */
13356     if (!PyArg_ParseTuple(args, "y#:sha1_digest", &in_data, &in_data_len))
13357         return NULL;
13358 #else
13359     if (!PyArg_ParseTuple(args, "t#:sha1_digest", &in_data, &in_data_len))
13360         return NULL;
13361 #endif
13362 
13363     if ((py_out_buf = PyBytes_FromStringAndSize(NULL, SHA1_LENGTH)) == NULL) {
13364         return NULL;
13365     }
13366 
13367     if ((out_buf = PyBytes_AsString(py_out_buf)) == NULL) {
13368         return NULL;
13369     }
13370 
13371     if (PK11_HashBuf(SEC_OID_SHA1, out_buf, in_data, in_data_len) != SECSuccess) {
13372         return set_nspr_error(NULL);
13373     }
13374 
13375     return py_out_buf;
13376 }
13377 
13378 PyDoc_STRVAR(pk11_sha256_digest_doc,
13379 "sha256_digest(data) --> digest\n\
13380 \n\
13381 :Parameters:\n\
13382     data : buffer or string\n\
13383         buffer the digest will be computed for\n\
13384 \n\
13385 Returns 32 octet SHA256 digest data as buffer object.\n\
13386 \n\
13387 Note, if a hexidecimal string representation is desired then pass\n\
13388 result to data_to_hex()\n\
13389 ");
13390 
13391 static PyObject *
pk11_sha256_digest(PyObject * self,PyObject * args)13392 pk11_sha256_digest(PyObject *self, PyObject *args)
13393 {
13394     unsigned char *in_data = NULL;
13395     Py_ssize_t in_data_len = 0;
13396     PyObject *py_out_buf = NULL;
13397     void *out_buf;
13398 
13399     TraceMethodEnter(self);
13400 
13401 #if PY_MAJOR_VERSION >= 3
13402     /* Py2 -> Py3 difference is t# -> y# */
13403     if (!PyArg_ParseTuple(args, "y#:sha256_digest", &in_data, &in_data_len))
13404         return NULL;
13405 #else
13406     if (!PyArg_ParseTuple(args, "t#:sha256_digest", &in_data, &in_data_len))
13407         return NULL;
13408 #endif
13409 
13410     if ((py_out_buf = PyBytes_FromStringAndSize(NULL, SHA256_LENGTH)) == NULL) {
13411         return NULL;
13412     }
13413 
13414     if ((out_buf = PyBytes_AsString(py_out_buf)) == NULL) {
13415         return NULL;
13416     }
13417 
13418     if (PK11_HashBuf(SEC_OID_SHA256, out_buf, in_data, in_data_len) != SECSuccess) {
13419         return set_nspr_error(NULL);
13420     }
13421 
13422     return py_out_buf;
13423 }
13424 
13425 PyDoc_STRVAR(pk11_sha512_digest_doc,
13426 "sha512_digest(data) --> digest\n\
13427 \n\
13428 :Parameters:\n\
13429     data : buffer or string\n\
13430         buffer the digest will be computed for\n\
13431 \n\
13432 Returns 64 octet SHA512 digest data as buffer object.\n\
13433 \n\
13434 Note, if a hexidecimal string representation is desired then pass\n\
13435 result to data_to_hex()\n\
13436 ");
13437 static PyObject *
pk11_sha512_digest(PyObject * self,PyObject * args)13438 pk11_sha512_digest(PyObject *self, PyObject *args)
13439 {
13440     unsigned char *in_data = NULL;
13441     Py_ssize_t in_data_len = 0;
13442     PyObject *py_out_buf = NULL;
13443     void *out_buf;
13444 
13445     TraceMethodEnter(self);
13446 
13447 #if PY_MAJOR_VERSION >= 3
13448     /* Py2 -> Py3 difference is t# -> y# */
13449     if (!PyArg_ParseTuple(args, "y#:sha512_digest", &in_data, &in_data_len))
13450         return NULL;
13451 #else
13452     if (!PyArg_ParseTuple(args, "t#:sha512_digest", &in_data, &in_data_len))
13453         return NULL;
13454 #endif
13455 
13456     if ((py_out_buf = PyBytes_FromStringAndSize(NULL, SHA512_LENGTH)) == NULL) {
13457         return NULL;
13458     }
13459 
13460     if ((out_buf = PyBytes_AsString(py_out_buf)) == NULL) {
13461         return NULL;
13462     }
13463 
13464     if (PK11_HashBuf(SEC_OID_SHA512, out_buf, in_data, in_data_len) != SECSuccess) {
13465         return set_nspr_error(NULL);
13466     }
13467 
13468     return py_out_buf;
13469 }
13470 
13471 /* ========================================================================== */
13472 /* ============================== PK11Slot Class ============================ */
13473 /* ========================================================================== */
13474 
13475 /* ============================ Attribute Access ============================ */
13476 
13477 static PyObject *
PK11_get_slot_name(PK11Slot * self,void * closure)13478 PK11_get_slot_name(PK11Slot *self, void *closure)
13479 {
13480     char *slot_name = NULL;
13481 
13482     TraceMethodEnter(self);
13483 
13484     if ((slot_name = PK11_GetSlotName(self->slot)) == NULL) {
13485         Py_RETURN_NONE;
13486     }
13487 
13488     return PyUnicode_FromString(slot_name);
13489 }
13490 
13491 static PyObject *
PK11_get_token_name(PK11Slot * self,void * closure)13492 PK11_get_token_name(PK11Slot *self, void *closure)
13493 {
13494     char *token_name = NULL;
13495 
13496     TraceMethodEnter(self);
13497 
13498     if ((token_name = PK11_GetTokenName(self->slot)) == NULL) {
13499         Py_RETURN_NONE;
13500     }
13501 
13502     return PyUnicode_FromString(token_name);
13503 }
13504 
13505 static
13506 PyGetSetDef PK11Slot_getseters[] = {
13507     {"slot_name",  (getter)PK11_get_slot_name,  (setter)NULL, "slot name", NULL},
13508     {"token_name", (getter)PK11_get_token_name, (setter)NULL, "token name", NULL},
13509     {NULL}  /* Sentinel */
13510 };
13511 
13512 static PyMemberDef PK11Slot_members[] = {
13513     {NULL}  /* Sentinel */
13514 };
13515 
13516 /* ============================== Class Methods ============================= */
13517 
13518 /* ========== Slot Info Functions ========== */
13519 
13520 // FIXME: should these be properties rather than methods?
13521 
13522 PyDoc_STRVAR(PK11Slot_is_hw_doc,
13523 "is_hw() -> bool\n\
13524 \n\
13525 Returns True if the slot is implemented in hardware, False otherwise.\n\
13526 ");
13527 static PyObject *
PK11Slot_is_hw(PK11Slot * self,PyObject * args)13528 PK11Slot_is_hw(PK11Slot *self, PyObject *args)
13529 {
13530     TraceMethodEnter(self);
13531 
13532     if (PK11_IsHW(self->slot))
13533         Py_RETURN_TRUE;
13534     else
13535         Py_RETURN_FALSE;
13536 
13537 }
13538 
13539 PyDoc_STRVAR(PK11Slot_is_present_doc,
13540 "is_present() -> bool\n\
13541 \n\
13542 Returns True if the slot's token present, False otherwise.\n\
13543 ");
13544 static PyObject *
PK11Slot_is_present(PK11Slot * self,PyObject * args)13545 PK11Slot_is_present(PK11Slot *self, PyObject *args)
13546 {
13547     TraceMethodEnter(self);
13548 
13549     if (PK11_IsPresent(self->slot))
13550         Py_RETURN_TRUE;
13551     else
13552         Py_RETURN_FALSE;
13553 
13554 }
13555 
13556 PyDoc_STRVAR(PK11Slot_is_read_only_doc,
13557 "is_read_only() -> bool\n\
13558 \n\
13559 Returns True if the the slot is read-only, False otherwise.\n\
13560 ");
13561 static PyObject *
PK11Slot_is_read_only(PK11Slot * self,PyObject * args)13562 PK11Slot_is_read_only(PK11Slot *self, PyObject *args)
13563 {
13564     TraceMethodEnter(self);
13565 
13566     if (PK11_IsReadOnly(self->slot))
13567         Py_RETURN_TRUE;
13568     else
13569         Py_RETURN_FALSE;
13570 
13571 }
13572 
13573 PyDoc_STRVAR(PK11Slot_is_internal_doc,
13574 "is_internal() -> bool\n\
13575 \n\
13576 Returns True if the the slot is internal, False otherwise.\n\
13577 ");
13578 static PyObject *
PK11Slot_is_internal(PK11Slot * self,PyObject * args)13579 PK11Slot_is_internal(PK11Slot *self, PyObject *args)
13580 {
13581     TraceMethodEnter(self);
13582 
13583     if (PK11_IsInternal(self->slot))
13584         Py_RETURN_TRUE;
13585     else
13586         Py_RETURN_FALSE;
13587 
13588 }
13589 
13590 PyDoc_STRVAR(PK11Slot_need_login_doc,
13591 "need_login() -> bool\n\
13592 \n\
13593 Returns True if there are some cryptographic functions that a\n\
13594 user must be logged in to perform, False otherwise.\n\
13595 ");
13596 static PyObject *
PK11Slot_need_login(PK11Slot * self,PyObject * args)13597 PK11Slot_need_login(PK11Slot *self, PyObject *args)
13598 {
13599     TraceMethodEnter(self);
13600 
13601     if (PK11_NeedLogin(self->slot))
13602         Py_RETURN_TRUE;
13603     else
13604         Py_RETURN_FALSE;
13605 
13606 }
13607 
13608 PyDoc_STRVAR(PK11Slot_need_user_init_doc,
13609 "need_user_init() -> bool\n\
13610 \n\
13611 Returns True if the slot needs to be logged into by\n\
13612 the user by providing their pin, False otherwise.\n\
13613 ");
13614 static PyObject *
PK11Slot_need_user_init(PK11Slot * self,PyObject * args)13615 PK11Slot_need_user_init(PK11Slot *self, PyObject *args)
13616 {
13617     TraceMethodEnter(self);
13618 
13619     if (PK11_NeedUserInit(self->slot))
13620         Py_RETURN_TRUE;
13621     else
13622         Py_RETURN_FALSE;
13623 
13624 }
13625 
13626 PyDoc_STRVAR(PK11Slot_is_friendly_doc,
13627 "is_friendly() -> bool\n\
13628 \n\
13629 Returns True if the slot allows certificates to be read\n\
13630 without logging in to the token, False otherwise.\n\
13631 ");
13632 static PyObject *
PK11Slot_is_friendly(PK11Slot * self,PyObject * args)13633 PK11Slot_is_friendly(PK11Slot *self, PyObject *args)
13634 {
13635     TraceMethodEnter(self);
13636 
13637     if (PK11_IsFriendly(self->slot))
13638         Py_RETURN_TRUE;
13639     else
13640         Py_RETURN_FALSE;
13641 
13642 }
13643 
13644 PyDoc_STRVAR(PK11Slot_is_removable_doc,
13645 "is_removable() -> bool\n\
13646 \n\
13647 Returns True if the token is removable, False otherwise.\n\
13648 ");
13649 static PyObject *
PK11Slot_is_removable(PK11Slot * self,PyObject * args)13650 PK11Slot_is_removable(PK11Slot *self, PyObject *args)
13651 {
13652     TraceMethodEnter(self);
13653 
13654     if (PK11_IsRemovable(self->slot))
13655         Py_RETURN_TRUE;
13656     else
13657         Py_RETURN_FALSE;
13658 
13659 }
13660 
13661 PyDoc_STRVAR(PK11Slot_has_protected_authentication_path_doc,
13662 "has_protected_authentication_path() -> bool\n\
13663 \n\
13664 Returns True if token has a \"protected authentication path\", whereby\n\
13665 a user can log into the token without passing a PIN through the\n\
13666 library, False otherwise.  An example might be a token with an\n\
13667 integrated key pad.\n\
13668 ");
13669 static PyObject *
PK11Slot_has_protected_authentication_path(PK11Slot * self,PyObject * args)13670 PK11Slot_has_protected_authentication_path(PK11Slot *self, PyObject *args)
13671 {
13672     TraceMethodEnter(self);
13673 
13674     if (PK11_ProtectedAuthenticationPath(self->slot))
13675         Py_RETURN_TRUE;
13676     else
13677         Py_RETURN_FALSE;
13678 
13679 }
13680 
13681 PyDoc_STRVAR(PK11Slot_is_disabled_doc,
13682 "is_disabled() -> bool\n\
13683 \n\
13684 Returns True if the slot is disabled, False otherwise.\n\
13685 ");
13686 static PyObject *
PK11Slot_is_disabled(PK11Slot * self,PyObject * args)13687 PK11Slot_is_disabled(PK11Slot *self, PyObject *args)
13688 {
13689     TraceMethodEnter(self);
13690 
13691     if (PK11_IsDisabled(self->slot))
13692         Py_RETURN_TRUE;
13693     else
13694         Py_RETURN_FALSE;
13695 
13696 }
13697 
13698 PyDoc_STRVAR(PK11Slot_has_root_certs_doc,
13699 "has_root_certs() -> bool\n\
13700 \n\
13701 Returns True if the slot contains the root certificate , False otherwise.\n\
13702 ");
13703 static PyObject *
PK11Slot_has_root_certs(PK11Slot * self,PyObject * args)13704 PK11Slot_has_root_certs(PK11Slot *self, PyObject *args)
13705 {
13706     TraceMethodEnter(self);
13707 
13708     if (PK11_HasRootCerts(self->slot))
13709         Py_RETURN_TRUE;
13710     else
13711         Py_RETURN_FALSE;
13712 
13713 }
13714 
13715 PyDoc_STRVAR(PK11Slot_get_disabled_reason_doc,
13716 "get_disabled_reason() -> integer\n\
13717 \n\
13718 Returns a diabled reason enumerated constant (i.e. PK11_DIS_*).\n\
13719 \n\
13720 May be one of:\n\
13721 \n\
13722     * PK11_DIS_NONE\n\
13723     * PK11_DIS_USER_SELECTED\n\
13724     * PK11_DIS_COULD_NOT_INIT_TOKEN\n\
13725     * PK11_DIS_TOKEN_VERIFY_FAILED\n\
13726     * PK11_DIS_TOKEN_NOT_PRESENT\n\
13727 \n\
13728 ");
13729 static PyObject *
PK11Slot_get_disabled_reason(PK11Slot * self,PyObject * args)13730 PK11Slot_get_disabled_reason(PK11Slot *self, PyObject *args)
13731 {
13732     TraceMethodEnter(self);
13733 
13734     return PyLong_FromLong(PK11_GetDisabledReason(self->slot));
13735 }
13736 
13737 PyDoc_STRVAR(PK11Slot_user_disable_doc,
13738 "user_disable() \n\
13739 \n\
13740 Prevents the slot from being used, and sets disable reason to\n\
13741 PK11_DIS_USER_SELECTED.\n\
13742 \n\
13743 Mechanisms that were on continue to stay on. Therefore, when the slot\n\
13744 is enabled again via `PK11Slot.user_enable()`, it will remember what\n\
13745 mechanisms needs to be turned on.\n\
13746 ");
13747 
13748 static PyObject *
PK11Slot_user_disable(PK11Slot * self,PyObject * args)13749 PK11Slot_user_disable(PK11Slot *self, PyObject *args)
13750 {
13751     TraceMethodEnter(self);
13752 
13753     if (!PK11_UserDisableSlot(self->slot)) {
13754         return set_nspr_error(_("unable to disable slot"));
13755     }
13756 
13757     Py_RETURN_NONE;
13758 }
13759 
13760 PyDoc_STRVAR(PK11Slot_user_enable_doc,
13761 "user_enable() \n\
13762 \n\
13763 Allow all mechanisms that are ON before `PK11Slot.user_disable()` was\n\
13764 called to be available again. Sets disable reason to PK11_DIS_NONE.\n\
13765 ");
13766 
13767 static PyObject *
PK11Slot_user_enable(PK11Slot * self,PyObject * args)13768 PK11Slot_user_enable(PK11Slot *self, PyObject *args)
13769 {
13770     TraceMethodEnter(self);
13771 
13772     if (!PK11_UserEnableSlot(self->slot)) {
13773         return set_nspr_error(_("unable to enable slot"));
13774     }
13775 
13776     Py_RETURN_NONE;
13777 }
13778 
13779 /* ========== Slot Password Management Functions ========== */
13780 
13781 PyDoc_STRVAR(PK11Slot_is_logged_in_doc,
13782 "is_logged_in([user_data1, ...]) -> bool\n\
13783 \n\
13784 :Parameters:\n\
13785     user_data1 : object ...\n\
13786         zero or more caller supplied parameters which will\n\
13787         be passed to the password callback function\n\
13788 \n\
13789 Return True if token is logged in, False otherwise.\n\
13790 ");
13791 
13792 static PyObject *
PK11Slot_is_logged_in(PK11Slot * self,PyObject * args)13793 PK11Slot_is_logged_in(PK11Slot *self, PyObject *args)
13794 {
13795     PyObject *pin_args = args;
13796     PRBool result;
13797 
13798     TraceMethodEnter(self);
13799 
13800     Py_INCREF(pin_args);
13801     result = PK11_IsLoggedIn(self->slot, pin_args);
13802     Py_DECREF(pin_args);
13803 
13804     if (result)
13805         Py_RETURN_TRUE;
13806     else
13807         Py_RETURN_FALSE;
13808 
13809     return NULL;
13810 }
13811 
13812 PyDoc_STRVAR(PK11Slot_authenticate_doc,
13813 "authenticate(load_certs=False, [user_data1, ...]) -> \n\
13814 \n\
13815 :Parameters:\n\
13816     load_certs : bool\n\
13817         If True load certificates after authenticating.\n\
13818 \n\
13819 Checks to see if token needs to be logged in.  If so it invokes the\n\
13820 password callback (set via `nss.set_password_callback()`) passing the\n\
13821 optional user_data parameters to the password callback.\n\
13822 ");
13823 
13824 static PyObject *
PK11Slot_authenticate(PK11Slot * self,PyObject * args)13825 PK11Slot_authenticate(PK11Slot *self, PyObject *args)
13826 {
13827     PyObject *py_load_certs = NULL;
13828     Py_ssize_t n_base_args = 1;
13829     Py_ssize_t argc;
13830     PyObject *parse_args = NULL;
13831     PyObject *pin_args = NULL;
13832     PRBool load_certs = PR_FALSE;
13833 
13834     TraceMethodEnter(self);
13835 
13836     argc = PyTuple_Size(args);
13837     if (argc == n_base_args) {
13838         Py_INCREF(args);
13839         parse_args = args;
13840     } else {
13841         parse_args = PyTuple_GetSlice(args, 0, n_base_args);
13842     }
13843     if (!PyArg_ParseTuple(parse_args, "|O!:authenticate",
13844                           &PyBool_Type, &py_load_certs)) {
13845         Py_DECREF(parse_args);
13846         return NULL;
13847     }
13848     Py_DECREF(parse_args);
13849 
13850     if (py_load_certs) {
13851         load_certs = PyBoolAsPRBool(py_load_certs);
13852     }
13853     pin_args = PyTuple_GetSlice(args, n_base_args, argc);
13854 
13855     Py_BEGIN_ALLOW_THREADS
13856     if (PK11_Authenticate(self->slot, load_certs, pin_args) != SECSuccess) {
13857 	Py_BLOCK_THREADS
13858         Py_DECREF(pin_args);
13859         return set_nspr_error("Unable to authenticate");
13860     }
13861     Py_END_ALLOW_THREADS
13862 
13863     Py_DECREF(pin_args);
13864 
13865     Py_RETURN_NONE;
13866 
13867 }
13868 
13869 PyDoc_STRVAR(PK11Slot_check_security_officer_passwd_doc,
13870 "check_security_officer_passwd(security_officer_passwd) -> bool\n\
13871 \n\
13872 Verify security officer password.\n\
13873 \n\
13874 :Parameters:\n\
13875     security_officer_passwd : string\n\
13876         Security Officer password.\n\
13877 ");
13878 
13879 static PyObject *
PK11Slot_check_security_officer_passwd(PK11Slot * self,PyObject * args)13880 PK11Slot_check_security_officer_passwd(PK11Slot *self, PyObject *args)
13881 {
13882     SECStatus result;
13883     PyObject *security_officer_passwd = NULL;
13884 
13885     TraceMethodEnter(self);
13886 
13887     if (!PyArg_ParseTuple(args, "O&:check_security_officer_passwd",
13888                           UTF8Convert, &security_officer_passwd
13889                           ))
13890         return NULL;
13891 
13892     result = PK11_CheckSSOPassword(self->slot,
13893                                    PyBytes_AsString(security_officer_passwd));
13894 
13895     if (result != SECSuccess && PORT_GetError() != SEC_ERROR_BAD_PASSWORD) {
13896         Py_DECREF(security_officer_passwd);
13897 	return set_nspr_error(NULL);
13898     }
13899 
13900     Py_DECREF(security_officer_passwd);
13901 
13902     if (result == SECSuccess) {
13903         Py_RETURN_TRUE;
13904     } else {
13905         Py_RETURN_FALSE;
13906     }
13907 }
13908 
13909 PyDoc_STRVAR(PK11Slot_check_user_passwd_doc,
13910 "check_user_passwd(user_passwd)\n\
13911 \n\
13912 Verify security officer password.\n\
13913 \n\
13914 :Parameters:\n\
13915     user_passwd : string\n\
13916         user password.\n\
13917 ");
13918 
13919 static PyObject *
PK11Slot_check_user_passwd(PK11Slot * self,PyObject * args)13920 PK11Slot_check_user_passwd(PK11Slot *self, PyObject *args)
13921 {
13922     SECStatus result;
13923     PyObject *user_passwd = NULL;
13924 
13925     TraceMethodEnter(self);
13926 
13927     if (!PyArg_ParseTuple(args, "O&:check_user_passwd",
13928                           UTF8Convert, &user_passwd
13929                           ))
13930         return NULL;
13931 
13932     result = PK11_CheckUserPassword(self->slot,
13933                                     PyBytes_AsString(user_passwd));
13934 
13935     if (result != SECSuccess && PORT_GetError() != SEC_ERROR_BAD_PASSWORD) {
13936         Py_DECREF(user_passwd);
13937 	return set_nspr_error(NULL);
13938     }
13939 
13940     Py_DECREF(user_passwd);
13941 
13942     if (result == SECSuccess) {
13943         Py_RETURN_TRUE;
13944     } else {
13945         Py_RETURN_FALSE;
13946     }
13947 }
13948 
13949 PyDoc_STRVAR(PK11Slot_change_passwd_doc,
13950 "change_passwd(old_passwd=None, new_passwd=None)\n\
13951 \n\
13952 Change the user password on the token.\n\
13953 \n\
13954 :Parameters:\n\
13955     old_passwd : string or None\n\
13956         Previouis password.\n\
13957     new_passwd : string or None\n\
13958         New password.\n\
13959 ");
13960 
13961 static PyObject *
PK11Slot_change_passwd(PK11Slot * self,PyObject * args,PyObject * kwds)13962 PK11Slot_change_passwd(PK11Slot *self, PyObject *args, PyObject *kwds)
13963 {
13964     static char *kwlist[] = {"old_passwd", "new_passwd", NULL};
13965     PyObject *old_passwd = NULL;
13966     PyObject *new_passwd = NULL;
13967 
13968     TraceMethodEnter(self);
13969 
13970     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|O&O&:change_passwd", kwlist,
13971                                      UTF8OrNoneConvert, &old_passwd,
13972                                      UTF8OrNoneConvert, &new_passwd
13973                                      ))
13974         return NULL;
13975 
13976     if (PK11_ChangePW(self->slot,
13977                       old_passwd ? PyBytes_AsString(old_passwd) : NULL,
13978                       new_passwd ? PyBytes_AsString(new_passwd) : NULL) != SECSuccess) {
13979         Py_XDECREF(old_passwd);
13980         Py_XDECREF(new_passwd);
13981 	return set_nspr_error(NULL);
13982     }
13983 
13984     Py_XDECREF(old_passwd);
13985     Py_XDECREF(new_passwd);
13986 
13987     Py_RETURN_NONE;
13988 
13989 }
13990 PyDoc_STRVAR(PK11Slot_init_pin_doc,
13991 "init_pin(security_officer_passwd=None, user_passwd=None)\n\
13992 \n\
13993 Initialize the token's pin for first use.\n\
13994 \n\
13995 :Parameters:\n\
13996     security_officer_passwd : string or None\n\
13997         Security Officer password used to unlock token.\n\
13998     user_passwd : string or None\n\
13999         User password to set as token pin.\n\
14000 ");
14001 
14002 static PyObject *
PK11Slot_init_pin(PK11Slot * self,PyObject * args,PyObject * kwds)14003 PK11Slot_init_pin(PK11Slot *self, PyObject *args, PyObject *kwds)
14004 {
14005     static char *kwlist[] = {"security_officer_passwd", "user_passwd", NULL};
14006     PyObject *security_officer_passwd = NULL;
14007     PyObject *user_passwd = NULL;
14008 
14009     TraceMethodEnter(self);
14010 
14011     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|O&O&:init_pin", kwlist,
14012                                      UTF8OrNoneConvert, &security_officer_passwd,
14013                                      UTF8OrNoneConvert, &user_passwd
14014                                      ))
14015         return NULL;
14016 
14017     if (PK11_InitPin(self->slot,
14018                      security_officer_passwd ? PyBytes_AsString(security_officer_passwd) : NULL,
14019                      user_passwd ? PyBytes_AsString(user_passwd) : NULL) != SECSuccess) {
14020         Py_XDECREF(security_officer_passwd);
14021         Py_XDECREF(user_passwd);
14022 	return set_nspr_error(NULL);
14023     }
14024 
14025     Py_XDECREF(security_officer_passwd);
14026     Py_XDECREF(user_passwd);
14027 
14028     Py_RETURN_NONE;
14029 
14030 }
14031 
14032 PyDoc_STRVAR(PK11Slot_logout_doc,
14033 "logout()l\n\
14034 \n\
14035 Logs a user out of a session destroying any objects\n\
14036 allocated on their behalf.\n\
14037 ");
14038 static PyObject *
PK11Slot_logout(PK11Slot * self,PyObject * args)14039 PK11Slot_logout(PK11Slot *self, PyObject *args)
14040 {
14041     TraceMethodEnter(self);
14042 
14043     if (PK11_Logout(self->slot) != SECSuccess) {
14044         return set_nspr_error("failed to logout of slot");
14045     }
14046 
14047     Py_RETURN_NONE;
14048 }
14049 
14050 /* ========== Slot Mapping Utility Functions ========== */
14051 
14052 PyDoc_STRVAR(PK11Slot_get_best_wrap_mechanism_doc,
14053 "get_best_wrap_mechanism() -> mechanism\n\
14054 \n\
14055 Find the best key wrap mechanism for this slot.\n\
14056 ");
14057 static PyObject *
PK11Slot_get_best_wrap_mechanism(PK11Slot * self,PyObject * args)14058 PK11Slot_get_best_wrap_mechanism(PK11Slot *self, PyObject *args)
14059 {
14060     CK_MECHANISM_TYPE mechanism;
14061 
14062     TraceMethodEnter(self);
14063 
14064     mechanism = PK11_GetBestWrapMechanism(self->slot);
14065     return PyLong_FromLong(mechanism);
14066 }
14067 
14068 
14069 PyDoc_STRVAR(PK11Slot_get_best_key_length_doc,
14070 "get_best_key_length(mechanism) -> length\n\
14071 \n\
14072 :Parameters:\n\
14073     mechanism : int\n\
14074         key mechanism enumeration constant (CKM_*)\n\
14075 \n\
14076 Return the best key length for this slot and mechanism.\n\
14077 A zero result means that token knows how long the key should be,\n\
14078 the result is typically used with key_gen(), token_key_gen(), or\n\
14079 token_key_gen_with_flags()\n\
14080 ");
14081 static PyObject *
PK11Slot_get_best_key_length(PK11Slot * self,PyObject * args)14082 PK11Slot_get_best_key_length(PK11Slot *self, PyObject *args)
14083 {
14084     unsigned long mechanism;
14085     int length;
14086 
14087     TraceMethodEnter(self);
14088 
14089     if (!PyArg_ParseTuple(args, "k:get_best_key_length", &mechanism))
14090         return NULL;
14091 
14092     length = PK11_GetBestKeyLength(self->slot, mechanism);
14093     return PyLong_FromLong(length);
14094 }
14095 
14096 PyDoc_STRVAR(PK11Slot_key_gen_doc,
14097 "key_gen(mechanism, sec_param, key_size, [user_data1, ...]) -> PK11SymKey object\n\
14098 \n\
14099 :Parameters:\n\
14100     mechanism : int\n\
14101         key mechanism enumeration constant (CKM_*)\n\
14102     sec_param : SecItem object or None\n\
14103         SecItem key parameters. None is also valid.\n\
14104     key_size : int\n\
14105         key length (use get_best_key_length())\n\
14106     user_dataN : object ...\n\
14107         zero or more caller supplied parameters which will\n\
14108         be passed to the password callback function\n\
14109 \n\
14110 Generate a symmetric key.\n\
14111 ");
14112 static PyObject *
PK11Slot_key_gen(PK11Slot * self,PyObject * args)14113 PK11Slot_key_gen(PK11Slot *self, PyObject *args)
14114 {
14115     Py_ssize_t n_base_args = 3;
14116     Py_ssize_t argc;
14117     PyObject *parse_args = NULL;
14118     PyObject *pin_args = NULL;
14119     unsigned long mechanism;
14120     int key_size;
14121     SecItem *py_sec_param;
14122     PK11SymKey *sym_key;
14123 
14124     TraceMethodEnter(self);
14125 
14126     argc = PyTuple_Size(args);
14127     if (argc == n_base_args) {
14128         Py_INCREF(args);
14129         parse_args = args;
14130     } else {
14131         parse_args = PyTuple_GetSlice(args, 0, n_base_args);
14132     }
14133     if (!PyArg_ParseTuple(parse_args, "kO&i:key_gen",
14134                           &mechanism, SecItemOrNoneConvert, &py_sec_param,
14135                           &key_size)) {
14136         Py_DECREF(parse_args);
14137         return NULL;
14138     }
14139     Py_DECREF(parse_args);
14140 
14141     pin_args = PyTuple_GetSlice(args, n_base_args, argc);
14142 
14143     Py_BEGIN_ALLOW_THREADS
14144     if ((sym_key = PK11_KeyGen(self->slot, mechanism, py_sec_param ? &py_sec_param->item : NULL,
14145                                key_size, pin_args)) == NULL) {
14146 	Py_BLOCK_THREADS
14147         Py_DECREF(pin_args);
14148         return set_nspr_error(NULL);
14149     }
14150     Py_END_ALLOW_THREADS
14151 
14152     Py_DECREF(pin_args);
14153 
14154     return PyPK11SymKey_new_from_PK11SymKey(sym_key);
14155 }
14156 
14157 PyDoc_STRVAR(PK11Slot_generate_key_pair_doc,
14158 "generate_key_pair(mechanism, key_params, token, sensitive, [user_data1, ...]) -> public_key, private_key\n\
14159 \n\
14160 :Parameters:\n\
14161     mechanism : int\n\
14162         key mechanism enumeration constant (CKM_*)\n\
14163     key_params : SecItem object or None\n\
14164         SecItem key parameters. None is also valid.\n\
14165     token : bool\n\
14166         If true the key is a token object otherwise it's a session object.\n\
14167     sensitive : bool\n\
14168         If a key is sensitive, certain attributes of the key cannot be\n\
14169         revealed in plaintext outside the token. It is also more\n\
14170         expensive to move between tokens.\n\
14171     user_dataN : object ...\n\
14172         zero or more caller supplied parameters which will\n\
14173         be passed to the password callback function\n\
14174 \n\
14175 Generate a public and private key pair.\n\
14176 \n\
14177 Example::\n\
14178 \n\
14179     # Generate a DSA key pair\n\
14180     key_params = nss.KEYPQGParams()\n\
14181     mechanism = nss.CKM_DSA_KEY_PAIR_GEN\n\
14182     slot = nss.get_best_slot(mechanism)\n\
14183     pub_key, priv_key = slot.generate_key_pair(mechanism, key_params, False, False)\n\
14184 \n\
14185     # Generate a DSA key pair\n\
14186     key_params = nss.RSAGenParams()\n\
14187     mechanism = nss.CKM_RSA_PKCS_KEY_PAIR_GEN\n\
14188     slot = nss.get_best_slot(mechanism)\n\
14189     pub_key, priv_key = slot.generate_key_pair(mechanism, key_params, False, False)\n\
14190 \n\
14191 ");
14192 static PyObject *
PK11Slot_generate_key_pair(PK11Slot * self,PyObject * args)14193 PK11Slot_generate_key_pair(PK11Slot *self, PyObject *args)
14194 {
14195     Py_ssize_t n_base_args = 4;
14196     Py_ssize_t argc;
14197     PyObject *parse_args = NULL;
14198     PyObject *pin_args = NULL;
14199     unsigned long mechanism;
14200     int token;
14201     int sensitive;
14202     PyObject *py_key_params;
14203     void *key_params = NULL;
14204     SECKEYPublicKey *pub_key = NULL;
14205     SECKEYPrivateKey *priv_key = NULL;
14206     PyObject *result_tuple = NULL;
14207     PyObject *py_pub_key = NULL;
14208     PyObject *py_priv_key = NULL;
14209 
14210     TraceMethodEnter(self);
14211 
14212     argc = PyTuple_Size(args);
14213     if (argc == n_base_args) {
14214         Py_INCREF(args);
14215         parse_args = args;
14216     } else {
14217         parse_args = PyTuple_GetSlice(args, 0, n_base_args);
14218     }
14219     if (!PyArg_ParseTuple(parse_args, "kOii:generate_key_pair",
14220                           &mechanism, &py_key_params, &token, &sensitive)) {
14221         goto fail;
14222     }
14223     Py_CLEAR(parse_args);
14224 
14225     pin_args = PyTuple_GetSlice(args, n_base_args, argc);
14226 
14227     switch(mechanism) {
14228     case CKM_RSA_PKCS_KEY_PAIR_GEN:
14229     case CKM_RSA_X9_31_KEY_PAIR_GEN:
14230         if (!PyRSAGenParams_Check(py_key_params)) {
14231             PyObject *mechanism_name = key_mechanism_type_to_pystr(mechanism);
14232             PyObject *mechanism_name_utf8 = PyBaseString_UTF8(mechanism_name, "mechanism name");
14233 
14234             PyErr_Format(PyExc_TypeError, "key_params for %s mechanism must be %.50s, not %.50s",
14235                          mechanism_name ? PyBytes_AsString(mechanism_name_utf8) : "unknown",
14236                          RSAGenParamsType.tp_name, Py_TYPE(py_key_params)->tp_name);
14237             Py_XDECREF(mechanism_name);
14238             Py_XDECREF(mechanism_name_utf8);
14239             goto fail;
14240         }
14241         key_params = &((RSAGenParams *)py_key_params)->params;
14242         break;
14243     case CKM_DSA_KEY_PAIR_GEN:
14244         if (!PyKEYPQGParams_Check(py_key_params)) {
14245             PyObject *mechanism_name = key_mechanism_type_to_pystr(mechanism);
14246             PyObject *mechanism_name_utf8 = PyBaseString_UTF8(mechanism_name, "mechanism name");
14247 
14248             PyErr_Format(PyExc_TypeError, "key_params for %s mechanism must be %.50s, not %.50s",
14249                          mechanism_name ? PyBytes_AsString(mechanism_name_utf8) : "unknown",
14250                          KEYPQGParamsType.tp_name, Py_TYPE(py_key_params)->tp_name);
14251             Py_XDECREF(mechanism_name);
14252             Py_XDECREF(mechanism_name_utf8);
14253             goto fail;
14254         }
14255         key_params = &((KEYPQGParams *)py_key_params)->params;
14256         break;
14257     default:
14258         break;
14259     }
14260 
14261     Py_BEGIN_ALLOW_THREADS
14262     if ((priv_key = PK11_GenerateKeyPair(self->slot, mechanism, key_params,
14263                                          &pub_key,
14264                                          token     ? PR_TRUE : PR_FALSE,
14265                                          sensitive ? PR_TRUE : PR_FALSE,
14266                                          pin_args)) == NULL) {
14267 	Py_BLOCK_THREADS
14268         set_nspr_error(NULL);
14269         goto fail;
14270     }
14271     Py_END_ALLOW_THREADS
14272 
14273     Py_CLEAR(pin_args);
14274 
14275     if ((py_pub_key = PublicKey_new_from_SECKEYPublicKey(pub_key)) == NULL) {
14276         goto fail;
14277     }
14278 
14279     if ((py_priv_key = PrivateKey_new_from_SECKEYPrivateKey(priv_key)) == NULL) {
14280         goto fail;
14281     }
14282 
14283     if ((result_tuple = PyTuple_New(2)) == NULL) {
14284         goto fail;
14285     }
14286 
14287     PyTuple_SetItem(result_tuple, 0, py_pub_key);
14288     PyTuple_SetItem(result_tuple, 1, py_priv_key);
14289 
14290     return result_tuple;
14291 
14292  fail:
14293     Py_XDECREF(parse_args);
14294     Py_XDECREF(pin_args);
14295     Py_XDECREF(result_tuple);
14296     return NULL;
14297 }
14298 
14299 PyDoc_STRVAR(PK11Slot_list_certs_doc,
14300 "list_certs() -> (`Certificate`, ...)\n\
14301 \n\
14302 Returns a tuple of `Certificate` objects found in the slot.\n\
14303 ");
14304 
14305 static PyObject *
PK11Slot_list_certs(PK11Slot * self,PyObject * args)14306 PK11Slot_list_certs(PK11Slot *self, PyObject *args)
14307 {
14308     CERTCertList *cert_list = NULL;
14309     PyObject *tuple = NULL;
14310 
14311     TraceMethodEnter(self);
14312 
14313     if ((cert_list = PK11_ListCertsInSlot(self->slot)) == NULL) {
14314         return set_nspr_error(NULL);
14315     }
14316 
14317     tuple = CERTCertList_to_tuple(cert_list, true);
14318     CERT_DestroyCertList(cert_list);
14319     return tuple;
14320 }
14321 
14322 PyDoc_STRVAR(PK11Slot_pbe_key_gen_doc,
14323 "pbe_key_gen(algid, password, [user_data1, ...]) -> PK11SymKey object\n\
14324 \n\
14325 :Parameters:\n\
14326     algid : AlgorithmID object\n\
14327         algorithm id\n\
14328     password : string\n\
14329         the password used to create the PBE Key\n\
14330     user_dataN : object ...\n\
14331         zero or more caller supplied parameters which will\n\
14332         be passed to the password callback function\n\
14333 \n\
14334 Generate a PBE symmetric key.\n\
14335 ");
14336 static PyObject *
PK11Slot_pbe_key_gen(PK11Slot * self,PyObject * args)14337 PK11Slot_pbe_key_gen(PK11Slot *self, PyObject *args)
14338 {
14339     Py_ssize_t n_base_args = 2;
14340     Py_ssize_t argc;
14341     PyObject *parse_args = NULL;
14342     PyObject *pin_args = NULL;
14343     AlgorithmID *py_algid = NULL;
14344     char *password = NULL;
14345     Py_ssize_t password_len = 0;
14346     SECItem pwitem;
14347     PK11SymKey *sym_key;
14348     PyObject *py_pwitem = NULL;
14349 
14350     TraceMethodEnter(self);
14351 
14352     argc = PyTuple_Size(args);
14353     if (argc == n_base_args) {
14354         Py_INCREF(args);
14355         parse_args = args;
14356     } else {
14357         parse_args = PyTuple_GetSlice(args, 0, n_base_args);
14358     }
14359     if (!PyArg_ParseTuple(parse_args, "O!s#:pbe_key_gen",
14360                           &AlgorithmIDType, &py_algid,
14361                           &password, &password_len)) {
14362         Py_DECREF(parse_args);
14363         return NULL;
14364     }
14365     Py_DECREF(parse_args);
14366 
14367     pin_args = PyTuple_GetSlice(args, n_base_args, argc);
14368 
14369     pwitem.data = (unsigned char *)password;
14370     pwitem.len = password_len;
14371 
14372     Py_BEGIN_ALLOW_THREADS
14373     if ((sym_key = PK11_PBEKeyGen(self->slot, &py_algid->id,
14374                                   &pwitem, PR_FALSE, pin_args)) == NULL) {
14375 	Py_BLOCK_THREADS
14376         Py_DECREF(pin_args);
14377         return set_nspr_error(NULL);
14378     }
14379     Py_END_ALLOW_THREADS
14380 
14381     Py_DECREF(pin_args);
14382 
14383     /*
14384      * Store the password in the symkey userData so it can be referenced
14385      * by PK11_GetPBECryptoMechanism
14386      */
14387     if ((py_pwitem = SecItem_new_from_SECItem(&pwitem, SECITEM_utf8_string)) == NULL) {
14388         PK11_FreeSymKey(sym_key);
14389         return NULL;
14390     }
14391 
14392     PK11_SetSymKeyUserData(sym_key, py_pwitem,
14393                            (PK11FreeDataFunc)SecItem_decref);
14394 
14395     return PyPK11SymKey_new_from_PK11SymKey(sym_key);
14396 }
14397 
14398 static PyObject *
PK11Slot_format_lines(PK11Slot * self,PyObject * args,PyObject * kwds)14399 PK11Slot_format_lines(PK11Slot *self, PyObject *args, PyObject *kwds)
14400 {
14401     static char *kwlist[] = {"level", NULL};
14402     int level = 0;
14403     PyObject *lines = NULL;
14404     PyObject *obj1 = NULL;
14405     PyObject *obj2 = NULL;
14406     PyObject *obj3 = NULL;
14407     PyObject *obj4 = NULL;
14408     PyObject *obj5 = NULL;
14409 
14410     TraceMethodEnter(self);
14411 
14412     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:format_lines", kwlist,
14413                                      &level))
14414         return NULL;
14415 
14416     if ((lines = PyList_New(0)) == NULL) {
14417         return NULL;
14418     }
14419 
14420     obj1 = PK11_get_slot_name(self, NULL);
14421     FMT_OBJ_AND_APPEND(lines, _("Slot Name"), obj1, level, fail);
14422     Py_CLEAR(obj1);
14423 
14424     obj1 = PK11_get_token_name(self, NULL);
14425     FMT_OBJ_AND_APPEND(lines, _("Token Name"), obj1, level, fail);
14426     Py_CLEAR(obj1);
14427 
14428     if ((obj1 = PyObject_CallMethod((PyObject *)self, "is_hw", NULL)) == NULL) {
14429         goto fail;
14430     }
14431     FMT_OBJ_AND_APPEND(lines, _("Is Hardware"), obj1, level, fail);
14432     Py_CLEAR(obj1);
14433 
14434     if ((obj1 = PyObject_CallMethod((PyObject *)self, "is_present", NULL)) == NULL) {
14435         goto fail;
14436     }
14437     FMT_OBJ_AND_APPEND(lines, _("Is Present"), obj1, level, fail);
14438     Py_CLEAR(obj1);
14439 
14440     if ((obj1 = PyObject_CallMethod((PyObject *)self, "is_read_only", NULL)) == NULL) {
14441         goto fail;
14442     }
14443     FMT_OBJ_AND_APPEND(lines, _("Is Read Only"), obj1, level, fail);
14444     Py_CLEAR(obj1);
14445 
14446     if ((obj1 = PyObject_CallMethod((PyObject *)self, "is_internal", NULL)) == NULL) {
14447         goto fail;
14448     }
14449     FMT_OBJ_AND_APPEND(lines, _("Is Internal"), obj1, level, fail);
14450     Py_CLEAR(obj1);
14451 
14452     if ((obj1 = PyObject_CallMethod((PyObject *)self, "need_login", NULL)) == NULL) {
14453         goto fail;
14454     }
14455     FMT_OBJ_AND_APPEND(lines, _("Needs Login"), obj1, level, fail);
14456     Py_CLEAR(obj1);
14457 
14458 
14459     if ((obj1 = PyObject_CallMethod((PyObject *)self, "need_user_init", NULL)) == NULL) {
14460         goto fail;
14461     }
14462     FMT_OBJ_AND_APPEND(lines, _("Needs User Init"), obj1, level, fail);
14463     Py_CLEAR(obj1);
14464 
14465     if ((obj1 = PyObject_CallMethod((PyObject *)self, "is_friendly", NULL)) == NULL) {
14466         goto fail;
14467     }
14468     FMT_OBJ_AND_APPEND(lines, _("Is Friendly"), obj1, level, fail);
14469     Py_CLEAR(obj1);
14470 
14471     if ((obj1 = PyObject_CallMethod((PyObject *)self, "is_removable", NULL)) == NULL) {
14472         goto fail;
14473     }
14474     FMT_OBJ_AND_APPEND(lines, _("Is Removable"), obj1, level, fail);
14475     Py_CLEAR(obj1);
14476 
14477     if ((obj1 = PyObject_CallMethod((PyObject *)self, "has_protected_authentication_path", NULL)) == NULL) {
14478         goto fail;
14479     }
14480     FMT_OBJ_AND_APPEND(lines, _("Has Protected Authentication Path"), obj1, level, fail);
14481     Py_CLEAR(obj1);
14482 
14483     if ((obj1 = PyObject_CallMethod((PyObject *)self, "is_disabled", NULL)) == NULL) {
14484         goto fail;
14485     }
14486     if ((obj2 = PyObject_CallMethod((PyObject *)self, "get_disabled_reason", NULL)) == NULL) {
14487         goto fail;
14488     }
14489     if ((obj3 = Py_BuildValue("(O)", obj2)) == NULL) {
14490         goto fail;
14491     }
14492 
14493     if ((obj4 = pk11_pk11_disabled_reason_str(NULL, obj3)) == NULL) {
14494         goto fail;
14495     }
14496 
14497     if ((obj5 = obj_sprintf("%s (%s)", obj1, obj4)) == NULL) {
14498         goto fail;
14499     }
14500 
14501     FMT_OBJ_AND_APPEND(lines, _("Is Disabled"), obj5, level, fail);
14502     Py_CLEAR(obj1);
14503     Py_CLEAR(obj2);
14504     Py_CLEAR(obj3);
14505     Py_CLEAR(obj4);
14506     Py_CLEAR(obj5);
14507 
14508     if ((obj1 = PyObject_CallMethod((PyObject *)self, "has_root_certs", NULL)) == NULL) {
14509         goto fail;
14510     }
14511     FMT_OBJ_AND_APPEND(lines, _("Has Root Certs"), obj1, level, fail);
14512     Py_CLEAR(obj1);
14513 
14514     if ((obj1 = PyObject_CallMethod((PyObject *)self, "get_best_wrap_mechanism", NULL)) == NULL) {
14515         goto fail;
14516     }
14517     obj2 = key_mechanism_type_to_pystr(PyLong_AsLong(obj1));
14518     if ((obj3 = obj_sprintf("%s (%#x)", obj2, obj1)) == NULL) {
14519         goto fail;
14520     }
14521     FMT_OBJ_AND_APPEND(lines, _("Best Wrap Mechanism"), obj3, level, fail);
14522     Py_CLEAR(obj1);
14523     Py_CLEAR(obj2);
14524     Py_CLEAR(obj3);
14525 
14526     return lines;
14527 
14528  fail:
14529     Py_XDECREF(obj1);
14530     Py_XDECREF(obj2);
14531     Py_XDECREF(obj3);
14532     Py_XDECREF(obj4);
14533     Py_XDECREF(obj5);
14534     Py_XDECREF(lines);
14535     return NULL;
14536 }
14537 
14538 static PyObject *
PK11Slot_format(PK11Slot * self,PyObject * args,PyObject * kwds)14539 PK11Slot_format(PK11Slot *self, PyObject *args, PyObject *kwds)
14540 {
14541     TraceMethodEnter(self);
14542 
14543     return format_from_lines((format_lines_func)PK11Slot_format_lines, (PyObject *)self, args, kwds);
14544 }
14545 
14546 static PyObject *
PK11Slot_str(PK11Slot * self)14547 PK11Slot_str(PK11Slot *self)
14548 {
14549     PyObject *py_formatted_result = NULL;
14550 
14551     TraceMethodEnter(self);
14552 
14553     py_formatted_result =  PK11Slot_format(self, empty_tuple, NULL);
14554     return py_formatted_result;
14555 
14556 }
14557 
14558 static PyMethodDef PK11Slot_methods[] = {
14559     {"format_lines",                      (PyCFunction)PK11Slot_format_lines,                      METH_VARARGS|METH_KEYWORDS, generic_format_lines_doc},
14560     {"format",                            (PyCFunction)PK11Slot_format,                            METH_VARARGS|METH_KEYWORDS, generic_format_doc},
14561     {"is_hw",                             (PyCFunction)PK11Slot_is_hw,                             METH_NOARGS,                PK11Slot_is_hw_doc},
14562     {"is_present",                        (PyCFunction)PK11Slot_is_present,                        METH_NOARGS,                PK11Slot_is_present_doc},
14563     {"is_read_only",                      (PyCFunction)PK11Slot_is_read_only,                      METH_NOARGS,                PK11Slot_is_read_only_doc},
14564     {"is_internal",                       (PyCFunction)PK11Slot_is_internal,                       METH_NOARGS,                PK11Slot_is_internal_doc},
14565     {"need_login",                        (PyCFunction)PK11Slot_need_login,                        METH_NOARGS,                PK11Slot_need_login_doc},
14566     {"need_user_init",                    (PyCFunction)PK11Slot_need_user_init,                    METH_NOARGS,                PK11Slot_need_user_init_doc},
14567     {"is_friendly",                       (PyCFunction)PK11Slot_is_friendly,                       METH_NOARGS,                PK11Slot_is_friendly_doc},
14568     {"is_removable",                      (PyCFunction)PK11Slot_is_removable,                      METH_NOARGS,                PK11Slot_is_removable_doc},
14569     {"is_logged_in",                      (PyCFunction)PK11Slot_is_logged_in,                      METH_NOARGS,                PK11Slot_is_logged_in_doc},
14570     {"has_protected_authentication_path", (PyCFunction)PK11Slot_has_protected_authentication_path, METH_NOARGS,                PK11Slot_has_protected_authentication_path_doc},
14571     {"is_disabled",                       (PyCFunction)PK11Slot_is_disabled,                       METH_NOARGS,                PK11Slot_is_disabled_doc},
14572     {"has_root_certs",                    (PyCFunction)PK11Slot_has_root_certs,                    METH_NOARGS,                PK11Slot_has_root_certs_doc},
14573     {"get_disabled_reason",               (PyCFunction)PK11Slot_get_disabled_reason,               METH_NOARGS,                PK11Slot_get_disabled_reason_doc},
14574     {"user_disable",                      (PyCFunction)PK11Slot_user_disable,                      METH_NOARGS,                PK11Slot_user_disable_doc},
14575     {"user_enable",                       (PyCFunction)PK11Slot_user_enable,                       METH_NOARGS,                PK11Slot_user_enable_doc},
14576     {"authenticate",                      (PyCFunction)PK11Slot_authenticate,                      METH_VARARGS,               PK11Slot_authenticate_doc},
14577     {"check_security_officer_passwd",     (PyCFunction)PK11Slot_check_security_officer_passwd,     METH_VARARGS,               PK11Slot_check_security_officer_passwd_doc},
14578     {"check_user_passwd",                 (PyCFunction)PK11Slot_check_user_passwd,                 METH_VARARGS,               PK11Slot_check_user_passwd_doc},
14579     {"change_passwd",                     (PyCFunction)PK11Slot_change_passwd,                     METH_VARARGS|METH_KEYWORDS, PK11Slot_change_passwd_doc},
14580     {"init_pin",                          (PyCFunction)PK11Slot_init_pin,                          METH_VARARGS|METH_KEYWORDS, PK11Slot_init_pin_doc},
14581     {"logout",                            (PyCFunction)PK11Slot_logout,                            METH_NOARGS,                PK11Slot_logout_doc},
14582     {"get_best_wrap_mechanism",           (PyCFunction)PK11Slot_get_best_wrap_mechanism,           METH_NOARGS,                PK11Slot_get_best_wrap_mechanism_doc},
14583     {"get_best_key_length",               (PyCFunction)PK11Slot_get_best_key_length,               METH_VARARGS,               PK11Slot_get_best_key_length_doc},
14584     {"key_gen",                           (PyCFunction)PK11Slot_key_gen,                           METH_VARARGS,               PK11Slot_key_gen_doc},
14585     {"generate_key_pair",                 (PyCFunction)PK11Slot_generate_key_pair,                 METH_VARARGS,               PK11Slot_generate_key_pair_doc},
14586     {"list_certs",                        (PyCFunction)PK11Slot_list_certs,                        METH_NOARGS,                PK11Slot_list_certs_doc},
14587     {"pbe_key_gen",                       (PyCFunction)PK11Slot_pbe_key_gen,                       METH_VARARGS,               PK11Slot_pbe_key_gen_doc},
14588     {NULL, NULL}  /* Sentinel */
14589 };
14590 
14591 /* =========================== Class Construction =========================== */
14592 
14593 static PyObject *
PK11Slot_new(PyTypeObject * type,PyObject * args,PyObject * kwds)14594 PK11Slot_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
14595 {
14596     PK11Slot *self;
14597 
14598     TraceObjNewEnter(type);
14599 
14600     if ((self = (PK11Slot *)type->tp_alloc(type, 0)) == NULL) {
14601         return NULL;
14602     }
14603     self->slot = NULL;
14604 
14605     TraceObjNewLeave(self);
14606     return (PyObject *)self;
14607 }
14608 
14609 static void
PK11Slot_dealloc(PK11Slot * self)14610 PK11Slot_dealloc(PK11Slot* self)
14611 {
14612     TraceMethodEnter(self);
14613 
14614     /* NSS_Shutdown might have been called before Python deallocates this object */
14615     if (NSS_IsInitialized()) {
14616         PK11_FreeSlot(self->slot);
14617     }
14618     Py_TYPE(self)->tp_free((PyObject*)self);
14619 }
14620 
14621 PyDoc_STRVAR(PK11Slot_doc,
14622 "An object representing a PKCS #11 Slot");
14623 
14624 static int
PK11Slot_init(PK11Slot * self,PyObject * args,PyObject * kwds)14625 PK11Slot_init(PK11Slot *self, PyObject *args, PyObject *kwds)
14626 {
14627     static char *kwlist[] = {NULL};
14628 
14629     TraceMethodEnter(self);
14630 
14631     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist))
14632         return -1;
14633 
14634     return 0;
14635 }
14636 
14637 static PyTypeObject PK11SlotType = {
14638     PyVarObject_HEAD_INIT(NULL, 0)
14639     "nss.nss.PK11Slot",				/* tp_name */
14640     sizeof(PK11Slot),				/* tp_basicsize */
14641     0,						/* tp_itemsize */
14642     (destructor)PK11Slot_dealloc,		/* tp_dealloc */
14643     0,						/* tp_print */
14644     0,						/* tp_getattr */
14645     0,						/* tp_setattr */
14646     0,						/* tp_compare */
14647     0,						/* tp_repr */
14648     0,						/* tp_as_number */
14649     0,						/* tp_as_sequence */
14650     0,						/* tp_as_mapping */
14651     0,						/* tp_hash */
14652     0,						/* tp_call */
14653     (reprfunc)PK11Slot_str,			/* tp_str */
14654     0,						/* tp_getattro */
14655     0,						/* tp_setattro */
14656     0,						/* tp_as_buffer */
14657     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,	/* tp_flags */
14658     PK11Slot_doc,				/* tp_doc */
14659     0,						/* tp_traverse */
14660     0,						/* tp_clear */
14661     0,						/* tp_richcompare */
14662     0,						/* tp_weaklistoffset */
14663     0,						/* tp_iter */
14664     0,						/* tp_iternext */
14665     PK11Slot_methods,				/* tp_methods */
14666     PK11Slot_members,				/* tp_members */
14667     PK11Slot_getseters,				/* tp_getset */
14668     0,						/* tp_base */
14669     0,						/* tp_dict */
14670     0,						/* tp_descr_get */
14671     0,						/* tp_descr_set */
14672     0,						/* tp_dictoffset */
14673     (initproc)PK11Slot_init,			/* tp_init */
14674     0,						/* tp_alloc */
14675     PK11Slot_new,				/* tp_new */
14676 };
14677 
14678 PyObject *
PK11Slot_new_from_PK11SlotInfo(PK11SlotInfo * slot)14679 PK11Slot_new_from_PK11SlotInfo(PK11SlotInfo *slot)
14680 {
14681     PK11Slot *self = NULL;
14682 
14683     TraceObjNewEnter(NULL);
14684 
14685     if ((self = (PK11Slot *) PK11SlotType.tp_new(&PK11SlotType, NULL, NULL)) == NULL) {
14686         return NULL;
14687     }
14688 
14689     self->slot = slot;
14690 
14691     TraceObjNewLeave(self);
14692     return (PyObject *) self;
14693 }
14694 
14695 /* ========================================================================== */
14696 /* =========================== PK11SymKey Class =========================== */
14697 /* ========================================================================== */
14698 
14699 /* ============================ Attribute Access ============================ */
14700 
14701 static PyObject *
PK11SymKey_get_mechanism(PyPK11SymKey * self,void * closure)14702 PK11SymKey_get_mechanism(PyPK11SymKey *self, void *closure)
14703 {
14704     TraceMethodEnter(self);
14705 
14706     return PyLong_FromLong(PK11_GetMechanism(self->pk11_sym_key));
14707 }
14708 
14709 static PyObject *
PK11SymKey_get_key_data(PyPK11SymKey * self,void * closure)14710 PK11SymKey_get_key_data(PyPK11SymKey *self, void *closure)
14711 {
14712     SECItem *sec_item;
14713 
14714     TraceMethodEnter(self);
14715 
14716     if (PK11_ExtractKeyValue(self->pk11_sym_key) != SECSuccess) {
14717         return set_nspr_error(NULL);
14718     }
14719 
14720     if ((sec_item = PK11_GetKeyData(self->pk11_sym_key)) == NULL) {
14721         return PyBytes_FromStringAndSize("", 0);
14722     }
14723 
14724     return PyBytes_FromStringAndSize((const char *)sec_item->data, sec_item->len);
14725 }
14726 
14727 static PyObject *
PK11SymKey_get_key_length(PyPK11SymKey * self,void * closure)14728 PK11SymKey_get_key_length(PyPK11SymKey *self, void *closure)
14729 {
14730     TraceMethodEnter(self);
14731 
14732     return PyLong_FromLong(PK11_GetKeyLength(self->pk11_sym_key));
14733 }
14734 
14735 static PyObject *
PK11SymKey_get_slot(PyPK11SymKey * self,void * closure)14736 PK11SymKey_get_slot(PyPK11SymKey *self, void *closure)
14737 {
14738     PK11SlotInfo *slot = NULL;
14739     PyObject *py_slot = NULL;
14740 
14741     TraceMethodEnter(self);
14742 
14743     slot = PK11_GetSlotFromKey(self->pk11_sym_key);
14744     if ((py_slot = PK11Slot_new_from_PK11SlotInfo(slot)) == NULL) {
14745         PyErr_SetString(PyExc_MemoryError, "unable to create PK11Slot object");
14746         return NULL;
14747     }
14748     return py_slot;
14749 }
14750 
14751 static
14752 PyGetSetDef PK11SymKey_getseters[] = {
14753     {"mechanism",  (getter)PK11SymKey_get_mechanism,  (setter)NULL, "CK_MECHANISM_TYPE mechanism", NULL},
14754     {"key_data",   (getter)PK11SymKey_get_key_data,   (setter)NULL, "key data", NULL},
14755     {"key_length", (getter)PK11SymKey_get_key_length, (setter)NULL, "key length", NULL},
14756     {"slot",       (getter)PK11SymKey_get_slot,       (setter)NULL, "slot", NULL},
14757     {NULL}  /* Sentinel */
14758 };
14759 
14760 static PyMemberDef PK11SymKey_members[] = {
14761     {NULL}  /* Sentinel */
14762 };
14763 
14764 /* ============================== Class Methods ============================= */
14765 
14766 static PyObject *
PK11SymKey_format_lines(PyPK11SymKey * self,PyObject * args,PyObject * kwds)14767 PK11SymKey_format_lines(PyPK11SymKey *self, PyObject *args, PyObject *kwds)
14768 {
14769     static char *kwlist[] = {"level", NULL};
14770     int level = 0;
14771     PyObject *lines = NULL;
14772     PyObject *obj1 = NULL;
14773     PyObject *obj2 = NULL;
14774     PyObject *obj3 = NULL;
14775 
14776     TraceMethodEnter(self);
14777 
14778     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:format_lines", kwlist,
14779                                      &level))
14780         return NULL;
14781 
14782     if ((lines = PyList_New(0)) == NULL) {
14783         return NULL;
14784     }
14785 
14786     obj1 = PK11SymKey_get_mechanism(self, NULL);
14787     obj2 = key_mechanism_type_to_pystr(PyLong_AsLong(obj1));
14788     if ((obj3 = obj_sprintf("%s (%#x)", obj2, obj1)) == NULL) {
14789         goto fail;
14790     }
14791     FMT_OBJ_AND_APPEND(lines, _("Mechanism"), obj3, level, fail);
14792     Py_CLEAR(obj1);
14793     Py_CLEAR(obj2);
14794     Py_CLEAR(obj3);
14795 
14796     obj1 = PK11SymKey_get_key_length(self, NULL);
14797     FMT_OBJ_AND_APPEND(lines, _("Key Length"), obj1, level, fail);
14798     Py_CLEAR(obj1);
14799 
14800     if ((obj1 = PK11SymKey_get_key_data(self, NULL)) != NULL) {
14801         FMT_LABEL_AND_APPEND(lines, _("Key Data"), level, fail);
14802         APPEND_OBJ_TO_HEX_LINES_AND_CLEAR(lines, obj1, level+1, fail);
14803     } else {
14804         PyObject *error_type, *error_value, *error_traceback;
14805 
14806         PyErr_Fetch(&error_type, &error_value, &error_traceback);
14807 
14808         obj1 = PyObject_String(error_value);
14809         FMT_OBJ_AND_APPEND(lines, _("Key Data"), obj1, level, fail);
14810         Py_CLEAR(obj1);
14811 
14812         Py_XDECREF(error_type);
14813         Py_XDECREF(error_value);
14814         Py_XDECREF(error_traceback);
14815     }
14816 
14817     obj1 = PK11SymKey_get_slot(self, NULL);
14818     FMT_LABEL_AND_APPEND(lines, _("PK11 Slot"), level, fail);
14819     CALL_FORMAT_LINES_AND_APPEND(lines, obj1, level+1, fail);
14820     Py_CLEAR(obj1);
14821 
14822     return lines;
14823  fail:
14824     Py_XDECREF(obj1);
14825     Py_XDECREF(obj2);
14826     Py_XDECREF(obj3);
14827     Py_XDECREF(lines);
14828     return NULL;
14829 }
14830 
14831 static PyObject *
PK11SymKey_format(PyPK11SymKey * self,PyObject * args,PyObject * kwds)14832 PK11SymKey_format(PyPK11SymKey *self, PyObject *args, PyObject *kwds)
14833 {
14834     TraceMethodEnter(self);
14835 
14836     return format_from_lines((format_lines_func)PK11SymKey_format_lines, (PyObject *)self, args, kwds);
14837 }
14838 
14839 static PyObject *
PK11SymKey_str(PyPK11SymKey * self)14840 PK11SymKey_str(PyPK11SymKey *self)
14841 {
14842     PyObject *py_formatted_result = NULL;
14843 
14844     TraceMethodEnter(self);
14845 
14846     py_formatted_result =  PK11SymKey_format(self, empty_tuple, NULL);
14847     return py_formatted_result;
14848 
14849 }
14850 
14851 PyDoc_STRVAR(PK11SymKey_derive_doc,
14852 "derive(mechanism, sec_param, target, operation, key_size) -> PK11SymKey\n\
14853 \n\
14854 :Parameters:\n\
14855     mechanism : int\n\
14856         key mechanism enumeration constant (CKM_*)\n\
14857     sec_param : SecItem object or None\n\
14858         mechanism parameters or None.\n\
14859     target : int\n\
14860         key mechanism enumeration constant (CKM_*)\n\
14861     operation : int\n\
14862         type of operation. A (CKA_*) constant\n\
14863         (e.g. CKA_ENCRYPT, CKA_DECRYPT, CKA_SIGN, CKA_VERIFY, CKA_DIGEST)\n\
14864     key_size : int\n\
14865         key size.\n\
14866 \n\
14867 Derive a new key from this key.\n\
14868 Return a key which can do exactly one operation, it is\n\
14869 ephemeral (session key).\n\
14870 ");
14871 static PyObject *
PK11SymKey_derive(PyPK11SymKey * self,PyObject * args)14872 PK11SymKey_derive(PyPK11SymKey *self, PyObject *args)
14873 {
14874     unsigned long mechanism;
14875     SecItem *py_sec_param;
14876     unsigned long target;
14877     unsigned long operation;
14878     int key_size;
14879     PK11SymKey *derived_key = NULL;
14880 
14881     TraceMethodEnter(self);
14882 
14883     if (!PyArg_ParseTuple(args, "kO&kki:derive",
14884                           &mechanism, SecItemOrNoneConvert, &py_sec_param,
14885                           &target, &operation, &key_size))
14886         return NULL;
14887 
14888     if ((derived_key = PK11_Derive(self->pk11_sym_key, mechanism,
14889                                    py_sec_param ? &py_sec_param->item : NULL,
14890                                    target, operation, key_size)) == NULL) {
14891         return set_nspr_error(NULL);
14892     }
14893 
14894     return PyPK11SymKey_new_from_PK11SymKey(derived_key);
14895 }
14896 
14897 PyDoc_STRVAR(PK11SymKey_wrap_sym_key_doc,
14898 "wrap_sym_key(mechanism, sec_param, sym_key) -> SecItem\n\
14899 \n\
14900 :Parameters:\n\
14901     mechanism : int\n\
14902         key mechanism enumeration constant (CKM_*)\n\
14903     sec_param : SecItem object or None\n\
14904         mechanism parameters or None.\n\
14905     sym_key : PK11SymKey object\n\
14906         the symmetric key to wrap\n\
14907 \n\
14908 Wrap (encrypt) the supplied sym_key using the mechanism\n\
14909 and parameter. Return the wrapped key as a SecItem.\n\
14910 ");
14911 static PyObject *
PK11SymKey_wrap_sym_key(PyPK11SymKey * self,PyObject * args)14912 PK11SymKey_wrap_sym_key(PyPK11SymKey *self, PyObject *args)
14913 {
14914     unsigned long mechanism;
14915     SecItem *py_sec_param;
14916     PyPK11SymKey *py_sym_key = NULL;
14917     SECItem wrapped_key;
14918 
14919     TraceMethodEnter(self);
14920 
14921     if (!PyArg_ParseTuple(args, "kO&O!:wrap_sym_key",
14922                           &mechanism, SecItemOrNoneConvert, &py_sec_param,
14923                           &PK11SymKeyType, &py_sym_key))
14924         return NULL;
14925 
14926     if (PK11_WrapSymKey(mechanism, py_sec_param ? &py_sec_param->item : NULL,
14927                         self->pk11_sym_key, py_sym_key->pk11_sym_key,
14928                         &wrapped_key) != SECSuccess) {
14929         return set_nspr_error(NULL);
14930     }
14931 
14932     return SecItem_new_from_SECItem(&wrapped_key, SECITEM_wrapped_key);
14933 }
14934 
14935 PyDoc_STRVAR(PK11SymKey_unwrap_sym_key_doc,
14936 "unwrap_sym_key(mechanism, sec_param, wrapped_key, target, operation, key_size) -> PK11SymKey\n\
14937 \n\
14938 :Parameters:\n\
14939     mechanism : int\n\
14940         key mechanism enumeration constant (CKM_*)\n\
14941     sec_param : SecItem object or None\n\
14942         mechanism parameters or None.\n\
14943     wrapped_key : SecItem object\n\
14944         the symmetric key to unwrap\n\
14945     target : int\n\
14946         key mechanism enumeration constant (CKM_*)\n\
14947     operation : int\n\
14948         type of operation. A (CKA_*) constant\n\
14949         (e.g. CKA_ENCRYPT, CKA_DECRYPT, CKA_SIGN, CKA_VERIFY, CKA_DIGEST)\n\
14950     key_size : int\n\
14951         key size.\n\
14952 \n\
14953 Unwrap (decrypt) the supplied wrapped key.\n\
14954 Return the unwrapped key as a PK11SymKey.\n\
14955 ");
14956 static PyObject *
PK11SymKey_unwrap_sym_key(PyPK11SymKey * self,PyObject * args)14957 PK11SymKey_unwrap_sym_key(PyPK11SymKey *self, PyObject *args)
14958 {
14959     unsigned long mechanism;
14960     SecItem *py_sec_param;
14961     unsigned long target;
14962     unsigned long operation;
14963     int key_size;
14964     SecItem *py_wrapped_key = NULL;
14965     PK11SymKey *sym_key = NULL;
14966 
14967     TraceMethodEnter(self);
14968 
14969     if (!PyArg_ParseTuple(args, "kO&O!kki:unwrap_sym_key",
14970                           &mechanism, SecItemOrNoneConvert, &py_sec_param,
14971                           &SecItemType, &py_wrapped_key,
14972                           &target, &operation, &key_size))
14973         return NULL;
14974 
14975     if ((sym_key = PK11_UnwrapSymKey(self->pk11_sym_key, mechanism,
14976                                      py_sec_param ? &py_sec_param->item : NULL,
14977                                      &py_wrapped_key->item,
14978                                      target, operation, key_size)) == NULL) {
14979         return set_nspr_error(NULL);
14980     }
14981 
14982     return PyPK11SymKey_new_from_PK11SymKey(sym_key);
14983 }
14984 
14985 
14986 static PyMethodDef PK11SymKey_methods[] = {
14987     {"format_lines",   (PyCFunction)PK11SymKey_format_lines,     METH_VARARGS|METH_KEYWORDS, generic_format_lines_doc},
14988     {"format",         (PyCFunction)PK11SymKey_format,           METH_VARARGS|METH_KEYWORDS, generic_format_doc},
14989     {"derive",         (PyCFunction)PK11SymKey_derive,           METH_VARARGS, PK11SymKey_derive_doc},
14990     {"wrap_sym_key",   (PyCFunction)PK11SymKey_wrap_sym_key,     METH_VARARGS, PK11SymKey_wrap_sym_key_doc},
14991     {"unwrap_sym_key", (PyCFunction)PK11SymKey_unwrap_sym_key,   METH_VARARGS, PK11SymKey_unwrap_sym_key_doc},
14992     {NULL, NULL}  /* Sentinel */
14993 };
14994 
14995 /* =========================== Class Construction =========================== */
14996 
14997 static void
PK11SymKey_dealloc(PyPK11SymKey * self)14998 PK11SymKey_dealloc(PyPK11SymKey* self)
14999 {
15000     TraceMethodEnter(self);
15001 
15002     if (self->pk11_sym_key) {
15003         PK11_FreeSymKey(self->pk11_sym_key);
15004     }
15005 
15006     Py_TYPE(self)->tp_free((PyObject*)self);
15007 }
15008 
15009 PyDoc_STRVAR(PK11SymKey_doc,
15010 "Holds a hash, encryption or signing context for multi-part operations.\n\
15011 ");
15012 static int
PK11SymKey_init(PyPK11SymKey * self,PyObject * args,PyObject * kwds)15013 PK11SymKey_init(PyPK11SymKey *self, PyObject *args, PyObject *kwds)
15014 {
15015     TraceMethodEnter(self);
15016 
15017     return 0;
15018 }
15019 
15020 static PyTypeObject PK11SymKeyType = {
15021     PyVarObject_HEAD_INIT(NULL, 0)
15022     "nss.nss.PK11SymKey",			/* tp_name */
15023     sizeof(PyPK11SymKey),			/* tp_basicsize */
15024     0,						/* tp_itemsize */
15025     (destructor)PK11SymKey_dealloc,		/* tp_dealloc */
15026     0,						/* tp_print */
15027     0,						/* tp_getattr */
15028     0,						/* tp_setattr */
15029     0,						/* tp_compare */
15030     0,						/* tp_repr */
15031     0,						/* tp_as_number */
15032     0,						/* tp_as_sequence */
15033     0,						/* tp_as_mapping */
15034     0,						/* tp_hash */
15035     0,						/* tp_call */
15036     (reprfunc)PK11SymKey_str,			/* tp_str */
15037     0,						/* tp_getattro */
15038     0,						/* tp_setattro */
15039     0,						/* tp_as_buffer */
15040     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,	/* tp_flags */
15041     PK11SymKey_doc,				/* tp_doc */
15042     0,						/* tp_traverse */
15043     0,						/* tp_clear */
15044     0,						/* tp_richcompare */
15045     0,						/* tp_weaklistoffset */
15046     0,						/* tp_iter */
15047     0,						/* tp_iternext */
15048     PK11SymKey_methods,				/* tp_methods */
15049     PK11SymKey_members,				/* tp_members */
15050     PK11SymKey_getseters,			/* tp_getset */
15051     0,						/* tp_base */
15052     0,						/* tp_dict */
15053     0,						/* tp_descr_get */
15054     0,						/* tp_descr_set */
15055     0,						/* tp_dictoffset */
15056     (initproc)PK11SymKey_init,			/* tp_init */
15057     0,						/* tp_alloc */
15058     0,/* NULL cannot be directly created */	/* tp_new */
15059 };
15060 
15061 static PyObject *
PyPK11SymKey_new_from_PK11SymKey(PK11SymKey * pk11_sym_key)15062 PyPK11SymKey_new_from_PK11SymKey(PK11SymKey *pk11_sym_key)
15063 {
15064     PyPK11SymKey *self = NULL;
15065 
15066     TraceObjNewEnter(NULL);
15067 
15068     if ((self = PyObject_NEW(PyPK11SymKey, &PK11SymKeyType)) == NULL) {
15069         return NULL;
15070     }
15071 
15072     self->pk11_sym_key = pk11_sym_key;
15073 
15074     TraceObjNewLeave(self);
15075     return (PyObject *) self;
15076 }
15077 
15078 /* ========================================================================== */
15079 /* ============================ PK11Context Class =========================== */
15080 /* ========================================================================== */
15081 
15082 /* ============================ Attribute Access ============================ */
15083 
15084 static
15085 PyGetSetDef PK11Context_getseters[] = {
15086     {NULL}  /* Sentinel */
15087 };
15088 
15089 static PyMemberDef PK11Context_members[] = {
15090     {NULL}  /* Sentinel */
15091 };
15092 
15093 /* ============================== Class Methods ============================= */
15094 
15095 PyDoc_STRVAR(PK11Context_digest_key_doc,
15096 "digest_key(sym_key)\n\
15097 \n\
15098 :Parameters:\n\
15099     sym_key : PK11SymKey object\n\
15100         symmetric key\n\
15101 \n\
15102 Continues a multiple-part message-digesting operation by digesting the\n\
15103 value of a secret key.\n\
15104 ");
15105 static PyObject *
PK11Context_digest_key(PyPK11Context * self,PyObject * args)15106 PK11Context_digest_key(PyPK11Context *self, PyObject *args)
15107 {
15108     PyPK11SymKey *py_sym_key;
15109 
15110     TraceMethodEnter(self);
15111 
15112     if (!PyArg_ParseTuple(args, "O!:digest_key", &PK11SymKeyType, &py_sym_key))
15113         return NULL;
15114 
15115     if (PK11_DigestKey(self->pk11_context, py_sym_key->pk11_sym_key) != SECSuccess) {
15116         return set_nspr_error(NULL);
15117     }
15118     Py_RETURN_NONE;
15119 }
15120 
15121 PyDoc_STRVAR(PK11Context_clone_context_doc,
15122 "clone_context(context) -> PK11Context\n\
15123 \n\
15124 :Parameters:\n\
15125     context : PK11Context object\n\
15126         The PK11Context to be cloned\n\
15127 \n\
15128 Create a new PK11Context which is clone of the supplied context.\n\
15129 ");
15130 static PyObject *
PK11Context_clone_context(PyPK11Context * self,PyObject * args)15131 PK11Context_clone_context(PyPK11Context *self, PyObject *args)
15132 {
15133     PK11Context *pk11_context;
15134     PyObject *py_pk11_context;
15135 
15136     TraceMethodEnter(self);
15137 
15138     if (!PyArg_ParseTuple(args, "O!:clone_context", &PK11ContextType, &py_pk11_context))
15139         return NULL;
15140 
15141     if ((pk11_context = PK11_CloneContext(self->pk11_context)) == NULL) {
15142         return set_nspr_error(NULL);
15143     }
15144 
15145     if ((py_pk11_context =
15146          PyPK11Context_new_from_PK11Context(pk11_context)) == NULL) {
15147         PyErr_SetString(PyExc_MemoryError, "unable to create PK11Context object");
15148         return NULL;
15149     }
15150 
15151     return py_pk11_context;
15152 }
15153 
15154 PyDoc_STRVAR(PK11Context_digest_begin_doc,
15155 "digest_begin()\n\
15156 \n\
15157 Start a new digesting or Mac'ing operation on this context.\n\
15158 ");
15159 static PyObject *
PK11Context_digest_begin(PyPK11Context * self,PyObject * args)15160 PK11Context_digest_begin(PyPK11Context *self, PyObject *args)
15161 {
15162     TraceMethodEnter(self);
15163 
15164     if (PK11_DigestBegin(self->pk11_context) != SECSuccess) {
15165         return set_nspr_error(NULL);
15166     }
15167 
15168     Py_RETURN_NONE;
15169 }
15170 
15171 PyDoc_STRVAR(PK11Context_digest_op_doc,
15172 "digest_op(data)\n\
15173 :Parameters:\n\
15174     data : any read buffer compatible object (e.g. buffer or string)\n\
15175         raw data to compute digest from\n\
15176 \n\
15177 Execute a digest/signature operation.\n\
15178 ");
15179 static PyObject *
PK11Context_digest_op(PyPK11Context * self,PyObject * args)15180 PK11Context_digest_op(PyPK11Context *self, PyObject *args)
15181 {
15182     const void *buffer = NULL;
15183     Py_ssize_t buffer_len;
15184 
15185     TraceMethodEnter(self);
15186 
15187 #if PY_MAJOR_VERSION >= 3
15188     /* Py2 -> Py3 difference is t# -> y# */
15189     if (!PyArg_ParseTuple(args, "y#:digest_op", &buffer, &buffer_len))
15190         return NULL;
15191 #else
15192     if (!PyArg_ParseTuple(args, "t#:digest_op", &buffer, &buffer_len))
15193         return NULL;
15194 #endif
15195 
15196     if (PK11_DigestOp(self->pk11_context, buffer, buffer_len) != SECSuccess) {
15197         return set_nspr_error(NULL);
15198     }
15199 
15200     Py_RETURN_NONE;
15201 }
15202 
15203 PyDoc_STRVAR(PK11Context_cipher_op_doc,
15204 "cipher_op(data) -> data\n\
15205 :Parameters:\n\
15206     data : any read buffer compatible object (e.g. buffer or string)\n\
15207         raw data to compute digest from\n\
15208 \n\
15209 Execute a digest/signature operation.\n\
15210 ");
15211 static PyObject *
PK11Context_cipher_op(PyPK11Context * self,PyObject * args)15212 PK11Context_cipher_op(PyPK11Context *self, PyObject *args)
15213 {
15214     const void *in_buf = NULL;
15215     void *out_buf = NULL;
15216     PyObject *py_out_bytes;
15217     Py_ssize_t in_buf_len;
15218     Py_ssize_t out_buf_alloc_len;
15219     int suggested_out_len = 0, actual_out_len;
15220 
15221     TraceMethodEnter(self);
15222 
15223 #if PY_MAJOR_VERSION >= 3
15224     /* Py2 -> Py3 difference is t# -> y# */
15225     if (!PyArg_ParseTuple(args, "y#:cipher_op", &in_buf, &in_buf_len))
15226         return NULL;
15227 #else
15228     if (!PyArg_ParseTuple(args, "t#:cipher_op", &in_buf, &in_buf_len))
15229         return NULL;
15230 #endif
15231 
15232     /*
15233      * Create an output buffer to hold the result.
15234      */
15235 
15236     /*
15237      * We call the PK11 function with a NULL output buffer and it returns an
15238      * upper bound on the size of the output data buffer. We create a string to
15239      * hold the data using the upper bound as it's size. We then invoke the PK11
15240      * function again which performs the operation writing into string buffer.
15241      * It returns the exact number of bytes written. If the allocated size does
15242      * not equal the actual number of bytes written we resize the string before
15243      * returning it so the caller sees a string whose length exactly matches
15244      * the number of bytes written by the PK11 function.
15245      */
15246     if (PK11_CipherOp(self->pk11_context, NULL, &suggested_out_len, 0,
15247                       (unsigned char *)in_buf, in_buf_len) != SECSuccess) {
15248         return set_nspr_error(NULL);
15249     }
15250 
15251     out_buf_alloc_len = suggested_out_len;
15252 
15253     if ((py_out_bytes = PyBytes_FromStringAndSize(NULL, out_buf_alloc_len)) == NULL) {
15254         return NULL;
15255     }
15256     out_buf = PyBytes_AsString(py_out_bytes);
15257 
15258     /*
15259      * Now that we have both the input and output buffers perform the cipher operation.
15260      */
15261     if (PK11_CipherOp(self->pk11_context, out_buf, &actual_out_len, out_buf_alloc_len,
15262                       (unsigned char *)in_buf, in_buf_len) != SECSuccess) {
15263         Py_DECREF(py_out_bytes);
15264         return set_nspr_error(NULL);
15265     }
15266 
15267     if (actual_out_len != out_buf_alloc_len) {
15268         if (_PyBytes_Resize(&py_out_bytes, actual_out_len) < 0) {
15269         return NULL;
15270         }
15271     }
15272 
15273     return py_out_bytes;
15274 }
15275 
15276 PyDoc_STRVAR(PK11Context_finalize_doc,
15277 "finalize()\n\
15278 \n\
15279 Clean up cipher operation so that any pending multi-part\n\
15280 operations have been flushed. Any pending output which would\n\
15281 have been available as a result of the flush is discarded.\n\
15282 The context is left in a state available for reuse.\n\
15283 \n\
15284 WARNING: Currently context reuse only works for digest contexts\n\
15285 not encryption/decryption contexts\n\
15286 ");
15287 static PyObject *
PK11Context_finalize(PyPK11Context * self,PyObject * args)15288 PK11Context_finalize(PyPK11Context *self, PyObject *args)
15289 {
15290     TraceMethodEnter(self);
15291 
15292     if (PK11_Finalize(self->pk11_context) != SECSuccess) {
15293         return set_nspr_error(NULL);
15294     }
15295 
15296     Py_RETURN_NONE;
15297 }
15298 
15299 PyDoc_STRVAR(PK11Context_digest_final_doc,
15300 "digest_final() -> data\n\
15301 \n\
15302 Completes the multi-part cryptographic operation in progress\n\
15303 on this context and returns any final data which may have been\n\
15304 pending in the context (i.e. the output data is flushed from the\n\
15305 context). If there was no final data the returned\n\
15306 data buffer will have a length of zero.\n\
15307 ");
15308 static PyObject *
PK11Context_digest_final(PyPK11Context * self,PyObject * args)15309 PK11Context_digest_final(PyPK11Context *self, PyObject *args)
15310 {
15311     void *out_buf = NULL;
15312     Py_ssize_t out_buf_alloc_len;
15313     unsigned int suggested_out_len = 0, actual_out_len;
15314     PyObject *py_out_bytes;
15315     SECStatus result;
15316 
15317     TraceMethodEnter(self);
15318 
15319     /*
15320      * We call the PK11 function with a NULL output buffer and it returns an
15321      * upper bound on the size of the output data buffer. We create a string to
15322      * hold the data using the upper bound as it's size. We then invoke the PK11
15323      * function again which performs the operation writing into string buffer.
15324      * It returns the exact number of bytes written. If the allocated size does
15325      * not equal the actual number of bytes written we resize the string before
15326      * returning it so the caller sees a string whose length exactly matches
15327      * the number of bytes written by the PK11 function.
15328      *
15329      * NSS WART
15330      *
15331      * We must be careful to detect the case when the 1st call to
15332      * DigestFinal returns a zero output length and not call it
15333      * again. This is because when there is nothing further to do
15334      * DigestFinal will close the context and release its resources
15335      * even if all you're doing is performing a buffer size check. I
15336      * believe this is a violation of the PKCS11 C API spec which says
15337      * that a call to check buffer size has no side effect. I could
15338      * find no NSS documentation as to the defined behavior in NSS.
15339      * This has been filed as Bug 1095725.
15340      */
15341 
15342     if (PK11_DigestFinal(self->pk11_context, NULL, &suggested_out_len, 0) != SECSuccess) {
15343         return set_nspr_error(NULL);
15344     }
15345 
15346     out_buf_alloc_len = suggested_out_len;
15347 
15348     if ((py_out_bytes = PyBytes_FromStringAndSize(NULL, out_buf_alloc_len)) == NULL) {
15349         return NULL;
15350     }
15351     out_buf = PyBytes_AsString(py_out_bytes);
15352 
15353     result = PK11_DigestFinal(self->pk11_context, out_buf,
15354                               &actual_out_len, out_buf_alloc_len);
15355 
15356     if (result != SECSuccess) {
15357         /*
15358          * Did we hit the above bug? If so ignore it, otherwise report failure.
15359          */
15360         if (!(suggested_out_len == 0 &&
15361               PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE)) {
15362             Py_DECREF(py_out_bytes);
15363             return set_nspr_error(NULL);
15364         }
15365     }
15366 
15367     if (actual_out_len != out_buf_alloc_len) {
15368         if (_PyBytes_Resize(&py_out_bytes, actual_out_len) < 0) {
15369             return NULL;
15370         }
15371     }
15372 
15373     return py_out_bytes;
15374 }
15375 
15376 static PyMethodDef PK11Context_methods[] = {
15377     {"digest_key",    (PyCFunction)PK11Context_digest_key,    METH_VARARGS, PK11Context_digest_key_doc},
15378     {"clone_context", (PyCFunction)PK11Context_clone_context, METH_VARARGS, PK11Context_clone_context_doc},
15379     {"digest_begin",  (PyCFunction)PK11Context_digest_begin,  METH_NOARGS,  PK11Context_digest_begin_doc},
15380     {"digest_op",     (PyCFunction)PK11Context_digest_op,     METH_VARARGS, PK11Context_digest_op_doc},
15381     {"cipher_op",     (PyCFunction)PK11Context_cipher_op,     METH_VARARGS, PK11Context_cipher_op_doc},
15382     {"finalize",      (PyCFunction)PK11Context_finalize,      METH_NOARGS,  PK11Context_finalize_doc},
15383     {"digest_final",  (PyCFunction)PK11Context_digest_final,  METH_NOARGS,  PK11Context_digest_final_doc},
15384     {NULL, NULL}  /* Sentinel */
15385 };
15386 
15387 /* =========================== Class Construction =========================== */
15388 
15389 static PyObject *
PK11Context_new(PyTypeObject * type,PyObject * args,PyObject * kwds)15390 PK11Context_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
15391 {
15392     PyPK11Context *self;
15393 
15394     TraceObjNewEnter(type);
15395 
15396     if ((self = (PyPK11Context *)type->tp_alloc(type, 0)) == NULL) {
15397         return NULL;
15398     }
15399 
15400     self->pk11_context = NULL;
15401 
15402     TraceObjNewLeave(self);
15403     return (PyObject *)self;
15404 }
15405 
15406 static void
PK11Context_dealloc(PyPK11Context * self)15407 PK11Context_dealloc(PyPK11Context* self)
15408 {
15409     TraceMethodEnter(self);
15410 
15411     if (self->pk11_context) {
15412         PK11_DestroyContext(self->pk11_context, PR_TRUE);
15413     }
15414 
15415     Py_TYPE(self)->tp_free((PyObject*)self);
15416 }
15417 
15418 PyDoc_STRVAR(PK11Context_doc,
15419 "\n\
15420 ");
15421 static int
PK11Context_init(PyPK11Context * self,PyObject * args,PyObject * kwds)15422 PK11Context_init(PyPK11Context *self, PyObject *args, PyObject *kwds)
15423 {
15424     TraceMethodEnter(self);
15425 
15426     return 0;
15427 }
15428 
15429 static PyTypeObject PK11ContextType = {
15430     PyVarObject_HEAD_INIT(NULL, 0)
15431     "nss.nss.PK11Context",			/* tp_name */
15432     sizeof(PyPK11Context),			/* tp_basicsize */
15433     0,						/* tp_itemsize */
15434     (destructor)PK11Context_dealloc,		/* tp_dealloc */
15435     0,						/* tp_print */
15436     0,						/* tp_getattr */
15437     0,						/* tp_setattr */
15438     0,						/* tp_compare */
15439     0,						/* tp_repr */
15440     0,						/* tp_as_number */
15441     0,						/* tp_as_sequence */
15442     0,						/* tp_as_mapping */
15443     0,						/* tp_hash */
15444     0,						/* tp_call */
15445     0,						/* tp_str */
15446     0,						/* tp_getattro */
15447     0,						/* tp_setattro */
15448     0,						/* tp_as_buffer */
15449     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,	/* tp_flags */
15450     PK11Context_doc,				/* tp_doc */
15451     0,						/* tp_traverse */
15452     0,						/* tp_clear */
15453     0,						/* tp_richcompare */
15454     0,						/* tp_weaklistoffset */
15455     0,						/* tp_iter */
15456     0,						/* tp_iternext */
15457     PK11Context_methods,			/* tp_methods */
15458     PK11Context_members,			/* tp_members */
15459     PK11Context_getseters,			/* tp_getset */
15460     0,						/* tp_base */
15461     0,						/* tp_dict */
15462     0,						/* tp_descr_get */
15463     0,						/* tp_descr_set */
15464     0,						/* tp_dictoffset */
15465     (initproc)PK11Context_init,			/* tp_init */
15466     0,						/* tp_alloc */
15467     PK11Context_new,				/* tp_new */
15468 };
15469 
15470 static PyObject *
PyPK11Context_new_from_PK11Context(PK11Context * pk11_context)15471 PyPK11Context_new_from_PK11Context(PK11Context *pk11_context)
15472 
15473 {
15474     PyPK11Context *self = NULL;
15475 
15476     TraceObjNewEnter(NULL);
15477 
15478     if ((self = (PyPK11Context *) PK11ContextType.tp_new(&PK11ContextType, NULL, NULL)) == NULL) {
15479         return NULL;
15480     }
15481 
15482     self->pk11_context = pk11_context;
15483 
15484     TraceObjNewLeave(self);
15485     return (PyObject *) self;
15486 }
15487 
15488 /* ========================================================================== */
15489 /* ======================== CRLDistributionPt Class ========================= */
15490 /* ========================================================================== */
15491 
15492 /* ============================ Attribute Access ============================ */
15493 
15494 static PyObject *
CRLDistributionPt_get_crl_issuer(CRLDistributionPt * self,void * closure)15495 CRLDistributionPt_get_crl_issuer(CRLDistributionPt *self, void *closure)
15496 {
15497     TraceMethodEnter(self);
15498 
15499     if (!self->pt || !self->pt->crlIssuer) {
15500         Py_RETURN_NONE;
15501     }
15502     return GeneralName_new_from_CERTGeneralName(self->pt->crlIssuer);
15503 }
15504 
15505 static
15506 PyGetSetDef CRLDistributionPt_getseters[] = {
15507     {"issuer", (getter)CRLDistributionPt_get_crl_issuer, (setter)NULL,
15508      "returns the CRL Issuer as a `GeneralName` object if defined, returns None if not defined", NULL},
15509     {NULL}  /* Sentinel */
15510 };
15511 
15512 static PyMemberDef CRLDistributionPt_members[] = {
15513     {NULL}  /* Sentinel */
15514 };
15515 
15516 /* ============================== Class Methods ============================= */
15517 
15518 PyDoc_STRVAR(CRLDistributionPt_get_general_names_doc,
15519 "get_general_names(repr_kind=AsString) -> (general_name, ...)\n\
15520 \n\
15521 :Parameters:\n\
15522     repr_kind : RepresentationKind constant\n\
15523         Specifies what the contents of the returned tuple will be.\n\
15524         May be one of:\n\
15525 \n\
15526         AsObject\n\
15527             The general name as a nss.GeneralName object\n\
15528         AsString\n\
15529             The general name as a string.\n\
15530             (e.g. \"http://crl.geotrust.com/crls/secureca.crl\")\n\
15531         AsTypeString\n\
15532             The general name type as a string.\n\
15533              (e.g. \"URI\")\n\
15534         AsTypeEnum\n\
15535             The general name type as a general name type enumerated constant.\n\
15536              (e.g. nss.certURI )\n\
15537         AsLabeledString\n\
15538             The general name as a string with it's type prepended.\n\
15539             (e.g. \"URI: http://crl.geotrust.com/crls/secureca.crl\"\n\
15540 \n\
15541 Returns a tuple of general names in the CRL Distribution Point. If the\n\
15542 distribution point type is not nss.generalName or the list was empty then\n\
15543 the returned tuple will be empty.\n\
15544 \n\
15545 You may specify how the each member of the tuple is represented, by default\n\
15546 it will be as a string.\n\
15547 ");
15548 
15549 static PyObject *
CRLDistributionPt_get_general_names(CRLDistributionPt * self,PyObject * args,PyObject * kwds)15550 CRLDistributionPt_get_general_names(CRLDistributionPt *self, PyObject *args, PyObject *kwds)
15551 {
15552     static char *kwlist[] = {"repr_kind", NULL};
15553     int repr_kind = AsString;
15554 
15555     TraceMethodEnter(self);
15556 
15557     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:get_general_names", kwlist,
15558                                      &repr_kind))
15559         return NULL;
15560 
15561     return CRLDistributionPt_general_names_tuple(self, repr_kind);
15562 }
15563 
15564 PyDoc_STRVAR(CRLDistributionPt_get_reasons_doc,
15565 "get_reasons(repr_kind=AsEnumDescription) -> (reason, ...)\n\
15566 \n\
15567 :Parameters:\n\
15568     repr_kind : RepresentationKind constant\n\
15569         Specifies what the contents of the returned tuple will be.\n\
15570         May be one of:\n\
15571 \n\
15572         AsEnum\n\
15573             The enumerated constant.\n\
15574             (e.g. nss.crlEntryReasonCaCompromise)\n\
15575         AsEnumDescription\n\
15576             A friendly human readable description of the enumerated constant as a string.\n\
15577              (e.g. \"CA Compromise\")\n\
15578         AsIndex\n\
15579             The bit position within the bit string.\n\
15580 \n\
15581 Returns a tuple of reasons in the CRL Distribution Point. If no\n\
15582 reasons were defined the returned tuple will be empty.\n\
15583 \n\
15584 You may specify how the each member of the tuple is represented, by default\n\
15585 it will be as a string.\n\
15586 ");
15587 
15588 static PyObject *
CRLDistributionPt_get_reasons(CRLDistributionPt * self,PyObject * args,PyObject * kwds)15589 CRLDistributionPt_get_reasons(CRLDistributionPt *self, PyObject *args, PyObject *kwds)
15590 {
15591     static char *kwlist[] = {"repr_kind", NULL};
15592     int repr_kind = AsEnumDescription;
15593 
15594     TraceMethodEnter(self);
15595 
15596     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:get_reasons", kwlist,
15597                                      &repr_kind))
15598         return NULL;
15599 
15600     return crl_reason_bitstr_to_tuple(&self->pt->bitsmap, repr_kind);
15601 }
15602 
15603 PyObject *
CRLDistributionPt_format_lines(CRLDistributionPt * self,PyObject * args,PyObject * kwds)15604 CRLDistributionPt_format_lines(CRLDistributionPt *self, PyObject *args, PyObject *kwds)
15605 {
15606     static char *kwlist[] = {"level", NULL};
15607     int level = 0;
15608     Py_ssize_t len;
15609     PyObject *lines = NULL;
15610     PyObject *obj = NULL;
15611     PyObject *obj1 = NULL;
15612 
15613     TraceMethodEnter(self);
15614 
15615     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:format_lines", kwlist, &level))
15616         return NULL;
15617 
15618     if ((lines = PyList_New(0)) == NULL) {
15619         return NULL;
15620     }
15621 
15622     if (!self->pt) {
15623         return lines;
15624     }
15625 
15626     if (self->pt->distPointType == generalName) {
15627         if ((obj = CRLDistributionPt_general_names_tuple(self, AsString)) == NULL) {
15628             goto fail;
15629         }
15630         len = PyTuple_GET_SIZE(obj);
15631 
15632         if ((obj1 = PyUnicode_FromFormat("General Names: [%zd total]", len)) == NULL) {
15633             goto fail;
15634         }
15635         FMT_OBJ_AND_APPEND(lines, NULL, obj1, level, fail);
15636         Py_CLEAR(obj1);
15637 
15638         APPEND_LINES_AND_CLEAR(lines, obj, level+1, fail);
15639 
15640     } else if (self->pt->distPointType == relativeDistinguishedName) {
15641 
15642         if ((obj = RDN_new_from_CERTRDN(&self->pt->distPoint.relativeName)) == NULL) {
15643             goto fail;
15644         }
15645 
15646         FMT_OBJ_AND_APPEND(lines, _("Relative Distinguished Name"), obj, level, fail);
15647         Py_CLEAR(obj);
15648     } else {
15649         PyErr_Format(PyExc_ValueError, "unknown distribution point type (%d), "
15650                      "expected generalName or relativeDistinguishedName",
15651                      self->pt->distPointType);
15652         goto fail;
15653     }
15654 
15655     if ((obj = CRLDistributionPt_get_crl_issuer(self, NULL)) == NULL) {
15656         goto fail;
15657     }
15658 
15659     FMT_OBJ_AND_APPEND(lines, _("Issuer"), obj, level, fail);
15660     Py_CLEAR(obj);
15661 
15662     if ((obj = crl_reason_bitstr_to_tuple(&self->pt->bitsmap, AsEnumDescription)) == NULL) {
15663         goto fail;
15664     }
15665 
15666     FMT_OBJ_AND_APPEND(lines, _("Reasons"), obj, level, fail);
15667     Py_CLEAR(obj);
15668 
15669     return lines;
15670 
15671  fail:
15672     Py_XDECREF(lines);
15673     Py_XDECREF(obj);
15674     Py_XDECREF(obj1);
15675     return NULL;
15676 }
15677 
15678 static PyObject *
CRLDistributionPt_format(CRLDistributionPt * self,PyObject * args,PyObject * kwds)15679 CRLDistributionPt_format(CRLDistributionPt *self, PyObject *args, PyObject *kwds)
15680 {
15681     TraceMethodEnter(self);
15682 
15683     return format_from_lines((format_lines_func)CRLDistributionPt_format_lines, (PyObject *)self, args, kwds);
15684 }
15685 
15686 static PyObject *
CRLDistributionPt_str(CRLDistributionPt * self)15687 CRLDistributionPt_str(CRLDistributionPt *self)
15688 {
15689     PyObject *py_formatted_result = NULL;
15690 
15691     TraceMethodEnter(self);
15692 
15693     py_formatted_result =  CRLDistributionPt_format(self, empty_tuple, NULL);
15694     return py_formatted_result;
15695 
15696 }
15697 
15698 static PyObject *
CRLDistributionPt_repr(CRLDistributionPt * self)15699 CRLDistributionPt_repr(CRLDistributionPt *self)
15700 {
15701     PyObject *result = NULL;
15702     PyObject *rdn = NULL;
15703     PyObject *names = NULL;
15704     PyObject *name_str = NULL;
15705     PyObject *name_desc = NULL;
15706     PyObject *crl_issuer = NULL;
15707     PyObject *crl_issuer_str = NULL;
15708     PyObject *reasons = NULL;
15709     PyObject *reasons_str = NULL;
15710     PyObject *sep = NULL;
15711 
15712     if (!self->pt) {
15713         return PyUnicode_FromFormat("<%s object at %p>",
15714                                     Py_TYPE(self)->tp_name, self);
15715     }
15716 
15717     if ((sep = PyUnicode_FromString(", ")) == NULL) {
15718         goto exit;
15719     }
15720 
15721     if (self->pt->distPointType == generalName) {
15722         if ((names = CRLDistributionPt_general_names_tuple(self, AsString)) == NULL) {
15723             goto exit;
15724         }
15725 
15726         /* Paste them all together with ", " between. */
15727         if ((name_str = PyUnicode_Join(sep, names)) == NULL) {
15728             goto exit;
15729         }
15730 
15731         name_desc = PyUnicode_FromFormat(_("General Name List: [%U]"), name_str);
15732 
15733     } else if (self->pt->distPointType == relativeDistinguishedName) {
15734 
15735         if ((rdn = RDN_new_from_CERTRDN(&self->pt->distPoint.relativeName)) == NULL) {
15736             goto exit;
15737         }
15738 
15739         if ((name_str = PyObject_String(rdn)) == NULL) {
15740             goto exit;
15741         }
15742 
15743         name_desc = PyUnicode_FromFormat(_("Relative Distinguished Name: %U"), name_str);
15744 
15745     } else {
15746         PyErr_Format(PyExc_ValueError, "unknown distribution point type (%d), "
15747                      "expected generalName or relativeDistinguishedName",
15748                      self->pt->distPointType);
15749         goto exit;
15750     }
15751 
15752     if ((crl_issuer = CRLDistributionPt_get_crl_issuer(self, NULL)) == NULL) {
15753         goto exit;
15754     }
15755 
15756     if ((crl_issuer_str = PyObject_String(crl_issuer)) == NULL) {
15757         goto exit;
15758     }
15759 
15760     if ((reasons = crl_reason_bitstr_to_tuple(&self->pt->bitsmap, AsEnumDescription)) == NULL) {
15761         goto exit;
15762     }
15763 
15764     if ((reasons_str = PyUnicode_Join(sep, reasons)) == NULL) {
15765         goto exit;
15766     }
15767 
15768     result = PyUnicode_FromFormat("%U, Issuer: %U, Reasons: [%U]",
15769                                   name_desc, crl_issuer_str, reasons_str);
15770 
15771  exit:
15772     Py_XDECREF(rdn);
15773     Py_XDECREF(names);
15774     Py_XDECREF(name_str);
15775     Py_XDECREF(name_desc);
15776     Py_XDECREF(crl_issuer);
15777     Py_XDECREF(crl_issuer_str);
15778     Py_XDECREF(reasons);
15779     Py_XDECREF(reasons_str);
15780     Py_XDECREF(sep);
15781 
15782     return result;
15783 }
15784 
15785 static PyMethodDef CRLDistributionPt_methods[] = {
15786     {"format_lines",      (PyCFunction)CRLDistributionPt_format_lines,      METH_VARARGS|METH_KEYWORDS, generic_format_lines_doc},
15787     {"format",            (PyCFunction)CRLDistributionPt_format,            METH_VARARGS|METH_KEYWORDS, generic_format_doc},
15788     {"get_general_names", (PyCFunction)CRLDistributionPt_get_general_names, METH_VARARGS|METH_KEYWORDS, CRLDistributionPt_get_general_names_doc},
15789     {"get_reasons",       (PyCFunction)CRLDistributionPt_get_reasons,       METH_VARARGS|METH_KEYWORDS, CRLDistributionPt_get_reasons_doc},
15790     {NULL, NULL}  /* Sentinel */
15791 };
15792 
15793 /* =========================== Class Construction =========================== */
15794 
15795 static PyObject *
CRLDistributionPt_new(PyTypeObject * type,PyObject * args,PyObject * kwds)15796 CRLDistributionPt_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
15797 {
15798     CRLDistributionPt *self;
15799 
15800     TraceObjNewEnter(type);
15801 
15802     if ((self = (CRLDistributionPt *)type->tp_alloc(type, 0)) == NULL) {
15803         return NULL;
15804     }
15805 
15806     if ((self->arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE)) == NULL) {
15807         type->tp_free(self);
15808         return set_nspr_error(NULL);
15809     }
15810 
15811     self->pt = NULL;
15812 
15813     TraceObjNewLeave(self);
15814     return (PyObject *)self;
15815 }
15816 
15817 static void
CRLDistributionPt_dealloc(CRLDistributionPt * self)15818 CRLDistributionPt_dealloc(CRLDistributionPt* self)
15819 {
15820     TraceMethodEnter(self);
15821 
15822     if (self->arena) {
15823         PORT_FreeArena(self->arena, PR_FALSE);
15824     }
15825 
15826     Py_TYPE(self)->tp_free((PyObject*)self);
15827 }
15828 
15829 PyDoc_STRVAR(CRLDistributionPt_doc,
15830 "An object representing a CRL Distribution Point");
15831 
15832 static int
CRLDistributionPt_init(CRLDistributionPt * self,PyObject * args,PyObject * kwds)15833 CRLDistributionPt_init(CRLDistributionPt *self, PyObject *args, PyObject *kwds)
15834 {
15835     static char *kwlist[] = {"arg1", NULL};
15836     PyObject *arg;
15837 
15838     TraceMethodEnter(self);
15839 
15840     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|i:CRLDistributionPt", kwlist,
15841                                      &arg))
15842         return -1;
15843 
15844     return 0;
15845 }
15846 
15847 static Py_ssize_t
CRLDistributionPt_general_names_count(CRLDistributionPt * self)15848 CRLDistributionPt_general_names_count(CRLDistributionPt *self)
15849 {
15850     if (!self->pt || self->pt->distPointType != generalName) {
15851         return 0;
15852     }
15853 
15854     return CERTGeneralName_list_count(self->pt->distPoint.fullName);
15855 }
15856 
15857 static PyObject *
CRLDistributionPt_general_names_tuple(CRLDistributionPt * self,RepresentationKind repr_kind)15858 CRLDistributionPt_general_names_tuple(CRLDistributionPt *self, RepresentationKind repr_kind)
15859 {
15860     Py_ssize_t n_names;
15861 
15862     n_names = CRLDistributionPt_general_names_count(self);
15863 
15864     if (n_names == 0) {
15865         Py_INCREF(empty_tuple);
15866         return empty_tuple;
15867     }
15868 
15869     return CERTGeneralName_list_to_tuple(self->pt->distPoint.fullName, repr_kind);
15870 }
15871 
15872 
15873 static PyTypeObject CRLDistributionPtType = {
15874     PyVarObject_HEAD_INIT(NULL, 0)
15875     "nss.nss.CRLDistributionPoint",		/* tp_name */
15876     sizeof(CRLDistributionPt),			/* tp_basicsize */
15877     0,						/* tp_itemsize */
15878     (destructor)CRLDistributionPt_dealloc,	/* tp_dealloc */
15879     0,						/* tp_print */
15880     0,						/* tp_getattr */
15881     0,						/* tp_setattr */
15882     0,						/* tp_compare */
15883     (reprfunc)CRLDistributionPt_repr,		/* tp_repr */
15884     0,						/* tp_as_number */
15885     0,						/* tp_as_sequence */
15886     0,						/* tp_as_mapping */
15887     0,						/* tp_hash */
15888     0,						/* tp_call */
15889     (reprfunc)CRLDistributionPt_str,		/* tp_str */
15890     0,						/* tp_getattro */
15891     0,						/* tp_setattro */
15892     0,						/* tp_as_buffer */
15893     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,	/* tp_flags */
15894     CRLDistributionPt_doc,			/* tp_doc */
15895     0,						/* tp_traverse */
15896     0,						/* tp_clear */
15897     0,						/* tp_richcompare */
15898     0,						/* tp_weaklistoffset */
15899     0,						/* tp_iter */
15900     0,						/* tp_iternext */
15901     CRLDistributionPt_methods,			/* tp_methods */
15902     CRLDistributionPt_members,			/* tp_members */
15903     CRLDistributionPt_getseters,		/* tp_getset */
15904     0,						/* tp_base */
15905     0,						/* tp_dict */
15906     0,						/* tp_descr_get */
15907     0,						/* tp_descr_set */
15908     0,						/* tp_dictoffset */
15909     (initproc)CRLDistributionPt_init,		/* tp_init */
15910     0,						/* tp_alloc */
15911     CRLDistributionPt_new,			/* tp_new */
15912 };
15913 
15914 PyObject *
CRLDistributionPt_new_from_CRLDistributionPoint(CRLDistributionPoint * pt)15915 CRLDistributionPt_new_from_CRLDistributionPoint(CRLDistributionPoint *pt)
15916 {
15917     CRLDistributionPt *self = NULL;
15918 
15919     TraceObjNewEnter(NULL);
15920 
15921     if ((self = (CRLDistributionPt *) CRLDistributionPtType.tp_new(&CRLDistributionPtType, NULL, NULL)) == NULL) {
15922         return NULL;
15923     }
15924 
15925     if (CERT_CopyCRLDistributionPoint(self->arena, &self->pt, pt) != SECSuccess) {
15926         set_nspr_error(NULL);
15927         Py_CLEAR(self);
15928         return NULL;
15929     }
15930 
15931     TraceObjNewLeave(self);
15932     return (PyObject *) self;
15933 }
15934 
15935 /* ========================================================================== */
15936 /* ======================== CRLDistributionPts Class ======================== */
15937 /* ========================================================================== */
15938 
15939 /* ============================ Attribute Access ============================ */
15940 
15941 static
15942 PyGetSetDef CRLDistributionPts_getseters[] = {
15943     {NULL}  /* Sentinel */
15944 };
15945 
15946 static PyMemberDef CRLDistributionPts_members[] = {
15947     {NULL}  /* Sentinel */
15948 };
15949 
15950 /* ============================== Class Methods ============================= */
15951 
15952 static PyObject *
CRLDistributionPts_format_lines(CRLDistributionPts * self,PyObject * args,PyObject * kwds)15953 CRLDistributionPts_format_lines(CRLDistributionPts *self, PyObject *args, PyObject *kwds)
15954 {
15955     static char *kwlist[] = {"level", NULL};
15956     int level = 0;
15957     PyObject *lines = NULL;
15958     PyObject *obj = NULL;
15959     Py_ssize_t len, i;
15960 
15961     TraceMethodEnter(self);
15962 
15963     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:format_lines", kwlist, &level))
15964         return NULL;
15965 
15966     if ((lines = PyList_New(0)) == NULL) {
15967         return NULL;
15968     }
15969 
15970     //
15971     len = PyObject_Size((PyObject *)self);
15972     if ((obj = PyUnicode_FromFormat("CRL Distribution Points: [%zd total]", len)) == NULL) {
15973         goto fail;
15974     }
15975     FMT_OBJ_AND_APPEND(lines, NULL, obj, level, fail);
15976     Py_CLEAR(obj);
15977 
15978     for (i = 0; i < len; i++) {
15979         if ((obj = PyUnicode_FromFormat("Point [%zd]:", i+1)) == NULL) {
15980             goto fail;
15981         }
15982         FMT_OBJ_AND_APPEND(lines, NULL, obj, level+1, fail);
15983         Py_CLEAR(obj);
15984         if ((obj = PySequence_GetItem((PyObject *)self, i)) == NULL) {
15985             goto fail;
15986         }
15987         CALL_FORMAT_LINES_AND_APPEND(lines, obj, level+2, fail);
15988         Py_CLEAR(obj);
15989     }
15990 
15991     return lines;
15992  fail:
15993     Py_XDECREF(obj);
15994     Py_XDECREF(lines);
15995     return NULL;
15996 }
15997 
15998 static PyObject *
CRLDistributionPts_format(CRLDistributionPts * self,PyObject * args,PyObject * kwds)15999 CRLDistributionPts_format(CRLDistributionPts *self, PyObject *args, PyObject *kwds)
16000 {
16001     TraceMethodEnter(self);
16002 
16003     return format_from_lines((format_lines_func)CRLDistributionPts_format_lines, (PyObject *)self, args, kwds);
16004 }
16005 
16006 static PyObject *
CRLDistributionPts_str(CRLDistributionPts * self)16007 CRLDistributionPts_str(CRLDistributionPts *self)
16008 {
16009     PyObject *py_formatted_result = NULL;
16010 
16011     TraceMethodEnter(self);
16012 
16013     py_formatted_result =  CRLDistributionPts_format(self, empty_tuple, NULL);
16014     return py_formatted_result;
16015 
16016 }
16017 
16018 /* =========================== Sequence Protocol ============================ */
16019 
16020 static Py_ssize_t
CERTCrlDistributionPoints_count(CERTCrlDistributionPoints * dist_pts)16021 CERTCrlDistributionPoints_count(CERTCrlDistributionPoints *dist_pts)
16022 {
16023     Py_ssize_t count;
16024     CRLDistributionPoint **pts;
16025 
16026     if (!dist_pts) return 0;
16027     for (pts = dist_pts->distPoints, count = 0; *pts; pts++, count++);
16028 
16029     return count;
16030 }
16031 
16032 static Py_ssize_t
CRLDistributionPts_length(CRLDistributionPts * self)16033 CRLDistributionPts_length(CRLDistributionPts *self)
16034 {
16035     if (!self->py_pts) return 0;
16036     return PyTuple_Size(self->py_pts);
16037 }
16038 
16039 static PyObject *
CRLDistributionPts_item(CRLDistributionPts * self,register Py_ssize_t i)16040 CRLDistributionPts_item(CRLDistributionPts *self, register Py_ssize_t i)
16041 {
16042     PyObject *py_pt = NULL;
16043 
16044     if (!self->py_pts) {
16045         return PyErr_Format(PyExc_ValueError, "%s is uninitialized", Py_TYPE(self)->tp_name);
16046     }
16047     py_pt = PyTuple_GetItem(self->py_pts, i);
16048     Py_XINCREF(py_pt);
16049     return py_pt;
16050 }
16051 
16052 static PyMethodDef CRLDistributionPts_methods[] = {
16053     {"format_lines", (PyCFunction)CRLDistributionPts_format_lines,   METH_VARARGS|METH_KEYWORDS, generic_format_lines_doc},
16054     {"format",       (PyCFunction)CRLDistributionPts_format,         METH_VARARGS|METH_KEYWORDS, generic_format_doc},
16055     {NULL, NULL}  /* Sentinel */
16056 };
16057 
16058 /* =========================== Class Construction =========================== */
16059 
16060 static int
CRLDistributionPts_init_from_SECItem(CRLDistributionPts * self,SECItem * item)16061 CRLDistributionPts_init_from_SECItem(CRLDistributionPts *self, SECItem *item)
16062 {
16063     CERTCrlDistributionPoints *dist_pts;
16064     CRLDistributionPoint **pts, *pt;
16065     PLArenaPool *arena;
16066     Py_ssize_t count, i;
16067     PyObject *py_pts = NULL;
16068 
16069     Py_CLEAR(self->py_pts);
16070 
16071     if ((arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE)) == NULL) {
16072         return -1;
16073     }
16074 
16075     if ((dist_pts = CERT_DecodeCRLDistributionPoints(arena, item)) == NULL) {
16076         PyErr_SetString(PyExc_ValueError, "Failed to parse CRL Distribution Point Extension");
16077         PORT_FreeArena(arena, PR_FALSE);
16078         return -1;
16079     }
16080 
16081     count = CERTCrlDistributionPoints_count(dist_pts);
16082 
16083     if ((py_pts = PyTuple_New(count)) == NULL) {
16084         PORT_FreeArena(arena, PR_FALSE);
16085 	return -1;
16086     }
16087 
16088     for (pts = dist_pts->distPoints, i = 0; (pt = *pts); pts++, i++) {
16089         PyObject *py_crl_dist_pt;
16090 
16091         if ((py_crl_dist_pt = CRLDistributionPt_new_from_CRLDistributionPoint(pt)) == NULL) {
16092             PORT_FreeArena(arena, PR_FALSE);
16093             Py_CLEAR(py_pts);
16094             return -1;
16095         }
16096 
16097         PyTuple_SetItem(py_pts, i, py_crl_dist_pt);
16098     }
16099 
16100     ASSIGN_NEW_REF(self->py_pts, py_pts);
16101 
16102     PORT_FreeArena(arena, PR_FALSE);
16103 
16104     return 0;
16105 }
16106 
16107 static PyObject *
CRLDistributionPts_new(PyTypeObject * type,PyObject * args,PyObject * kwds)16108 CRLDistributionPts_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
16109 {
16110     CRLDistributionPts *self;
16111 
16112     TraceObjNewEnter(type);
16113 
16114     if ((self = (CRLDistributionPts *)type->tp_alloc(type, 0)) == NULL) {
16115         return NULL;
16116     }
16117 
16118     self->py_pts = NULL;
16119 
16120     TraceObjNewLeave(self);
16121     return (PyObject *)self;
16122 }
16123 
16124 static int
CRLDistributionPts_traverse(CRLDistributionPts * self,visitproc visit,void * arg)16125 CRLDistributionPts_traverse(CRLDistributionPts *self, visitproc visit, void *arg)
16126 {
16127     TraceMethodEnter(self);
16128 
16129     Py_VISIT(self->py_pts);
16130     return 0;
16131 }
16132 
16133 static int
CRLDistributionPts_clear(CRLDistributionPts * self)16134 CRLDistributionPts_clear(CRLDistributionPts* self)
16135 {
16136     TraceMethodEnter(self);
16137 
16138     Py_CLEAR(self->py_pts);
16139     return 0;
16140 }
16141 
16142 static void
CRLDistributionPts_dealloc(CRLDistributionPts * self)16143 CRLDistributionPts_dealloc(CRLDistributionPts* self)
16144 {
16145     TraceMethodEnter(self);
16146 
16147     CRLDistributionPts_clear(self);
16148     Py_TYPE(self)->tp_free((PyObject*)self);
16149 }
16150 
16151 PyDoc_STRVAR(CRLDistributionPts_doc,
16152 "An object representing CRL Distribution Points list");
16153 
16154 static int
CRLDistributionPts_init(CRLDistributionPts * self,PyObject * args,PyObject * kwds)16155 CRLDistributionPts_init(CRLDistributionPts *self, PyObject *args, PyObject *kwds)
16156 {
16157     static char *kwlist[] = {"crl_dist_pt_extension", NULL};
16158     SecItem *py_sec_item;
16159 
16160     TraceMethodEnter(self);
16161 
16162     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!:CRLDistributionPts", kwlist,
16163                                      &SecItemType, &py_sec_item))
16164         return -1;
16165 
16166     return CRLDistributionPts_init_from_SECItem(self, &py_sec_item->item);
16167 }
16168 
16169 static PySequenceMethods CRLDistributionPts_as_sequence = {
16170     (lenfunc)CRLDistributionPts_length,		/* sq_length */
16171     0,						/* sq_concat */
16172     0,						/* sq_repeat */
16173     (ssizeargfunc)CRLDistributionPts_item,	/* sq_item */
16174     0,						/* sq_slice */
16175     0,						/* sq_ass_item */
16176     0,						/* sq_ass_slice */
16177     0,						/* sq_contains */
16178     0,						/* sq_inplace_concat */
16179     0,						/* sq_inplace_repeat */
16180 };
16181 
16182 static PyTypeObject CRLDistributionPtsType = {
16183     PyVarObject_HEAD_INIT(NULL, 0)
16184     "nss.nss.CRLDistributionPts",		/* tp_name */
16185     sizeof(CRLDistributionPts),			/* tp_basicsize */
16186     0,						/* tp_itemsize */
16187     (destructor)CRLDistributionPts_dealloc,	/* tp_dealloc */
16188     0,						/* tp_print */
16189     0,						/* tp_getattr */
16190     0,						/* tp_setattr */
16191     0,						/* tp_compare */
16192     0,						/* tp_repr */
16193     0,						/* tp_as_number */
16194     &CRLDistributionPts_as_sequence,		/* tp_as_sequence */
16195     0,						/* tp_as_mapping */
16196     0,						/* tp_hash */
16197     0,						/* tp_call */
16198     (reprfunc)CRLDistributionPts_str,		/* tp_str */
16199     0,						/* tp_getattro */
16200     0,						/* tp_setattro */
16201     0,						/* tp_as_buffer */
16202     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,	/* tp_flags */
16203     CRLDistributionPts_doc,			/* tp_doc */
16204     (traverseproc)CRLDistributionPts_traverse,	/* tp_traverse */
16205     (inquiry)CRLDistributionPts_clear,		/* tp_clear */
16206     0,						/* tp_richcompare */
16207     0,						/* tp_weaklistoffset */
16208     0,						/* tp_iter */
16209     0,						/* tp_iternext */
16210     CRLDistributionPts_methods,			/* tp_methods */
16211     CRLDistributionPts_members,			/* tp_members */
16212     CRLDistributionPts_getseters,		/* tp_getset */
16213     0,						/* tp_base */
16214     0,						/* tp_dict */
16215     0,						/* tp_descr_get */
16216     0,						/* tp_descr_set */
16217     0,						/* tp_dictoffset */
16218     (initproc)CRLDistributionPts_init,		/* tp_init */
16219     0,						/* tp_alloc */
16220     CRLDistributionPts_new,			/* tp_new */
16221 };
16222 
16223 PyObject *
CRLDistributionPts_new_from_SECItem(SECItem * item)16224 CRLDistributionPts_new_from_SECItem(SECItem *item)
16225 {
16226     CRLDistributionPts *self = NULL;
16227 
16228     TraceObjNewEnter(NULL);
16229 
16230     if ((self = (CRLDistributionPts *) CRLDistributionPtsType.tp_new(&CRLDistributionPtsType, NULL, NULL)) == NULL) {
16231         return NULL;
16232     }
16233 
16234     if (CRLDistributionPts_init_from_SECItem(self, item) < 0) {
16235         Py_CLEAR(self);
16236         return NULL;
16237     }
16238 
16239     TraceObjNewLeave(self);
16240     return (PyObject *) self;
16241 }
16242 
16243 /* ========================================================================== */
16244 /* ======================= AuthorityInfoAccess Class ======================== */
16245 /* ========================================================================== */
16246 
16247 /* ============================ Attribute Access ============================ */
16248 
16249 static PyObject *
AuthorityInfoAccess_get_method_oid(AuthorityInfoAccess * self,void * closure)16250 AuthorityInfoAccess_get_method_oid(AuthorityInfoAccess *self, void *closure)
16251 {
16252     TraceMethodEnter(self);
16253 
16254     return SecItem_new_from_SECItem(&self->aia->method, SECITEM_oid);
16255 }
16256 
16257 static PyObject *
AuthorityInfoAccess_get_method_tag(AuthorityInfoAccess * self,void * closure)16258 AuthorityInfoAccess_get_method_tag(AuthorityInfoAccess *self, void *closure)
16259 {
16260     TraceMethodEnter(self);
16261 
16262     return oid_secitem_to_pyint_tag(&self->aia->method);
16263 }
16264 
16265 static PyObject *
AuthorityInfoAccess_get_method_str(AuthorityInfoAccess * self,void * closure)16266 AuthorityInfoAccess_get_method_str(AuthorityInfoAccess *self, void *closure)
16267 {
16268     TraceMethodEnter(self);
16269 
16270     return oid_secitem_to_pystr_desc(&self->aia->method);
16271 }
16272 
16273 static PyObject *
AuthorityInfoAccess_get_location(AuthorityInfoAccess * self,void * closure)16274 AuthorityInfoAccess_get_location(AuthorityInfoAccess *self, void *closure)
16275 {
16276     TraceMethodEnter(self);
16277 
16278     return GeneralName_new_from_CERTGeneralName(self->aia->location);
16279 }
16280 
16281 static
16282 PyGetSetDef AuthorityInfoAccess_getseters[] = {
16283     {"method_oid", (getter)AuthorityInfoAccess_get_method_oid, (setter)NULL, "method OID as SecItem", NULL},
16284     {"method_tag", (getter)AuthorityInfoAccess_get_method_tag, (setter)NULL, "method TAG as a enumerated constant (e.g. tag) ", NULL},
16285     {"method_str", (getter)AuthorityInfoAccess_get_method_str, (setter)NULL, "method as string description", NULL},
16286     {"location", (getter)AuthorityInfoAccess_get_location,     (setter)NULL, "location as a `nss.GeneralName` object", NULL},
16287     {NULL}  /* Sentinel */
16288 };
16289 
16290 static PyMemberDef AuthorityInfoAccess_members[] = {
16291     {NULL}  /* Sentinel */
16292 };
16293 
16294 /* ============================== Class Methods ============================= */
16295 
16296 static PyObject *
AuthorityInfoAccess_format_lines(AuthorityInfoAccess * self,PyObject * args,PyObject * kwds)16297 AuthorityInfoAccess_format_lines(AuthorityInfoAccess *self, PyObject *args, PyObject *kwds)
16298 {
16299     static char *kwlist[] = {"level", NULL};
16300     int level = 0;
16301     PyObject *lines = NULL;
16302     PyObject *obj = NULL;
16303 
16304     TraceMethodEnter(self);
16305 
16306     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:format_lines", kwlist, &level))
16307         return NULL;
16308 
16309     if ((lines = PyList_New(0)) == NULL) {
16310         return NULL;
16311     }
16312 
16313     if (!self->aia) {
16314         return lines;
16315     }
16316 
16317     if ((obj = oid_secitem_to_pystr_desc(&self->aia->method)) == NULL) {
16318         goto fail;
16319     }
16320     FMT_OBJ_AND_APPEND(lines, _("Method"), obj, level, fail);
16321     Py_CLEAR(obj);
16322 
16323     if ((obj = CERTGeneralName_to_pystr_with_label(self->aia->location)) == NULL) {
16324         goto fail;
16325     }
16326     FMT_OBJ_AND_APPEND(lines, _("Location"), obj, level, fail);
16327     Py_CLEAR(obj);
16328 
16329     return lines;
16330  fail:
16331     Py_XDECREF(obj);
16332     Py_XDECREF(lines);
16333     return NULL;
16334 }
16335 
16336 static PyObject *
AuthorityInfoAccess_format(AuthorityInfoAccess * self,PyObject * args,PyObject * kwds)16337 AuthorityInfoAccess_format(AuthorityInfoAccess *self, PyObject *args, PyObject *kwds)
16338 {
16339     TraceMethodEnter(self);
16340 
16341     return format_from_lines((format_lines_func)AuthorityInfoAccess_format_lines, (PyObject *)self, args, kwds);
16342 }
16343 
16344 static PyObject *
AuthorityInfoAccess_str(AuthorityInfoAccess * self)16345 AuthorityInfoAccess_str(AuthorityInfoAccess *self)
16346 {
16347     PyObject *py_formatted_result = NULL;
16348 
16349     TraceMethodEnter(self);
16350 
16351     py_formatted_result =  AuthorityInfoAccess_format(self, empty_tuple, NULL);
16352     return py_formatted_result;
16353 
16354 }
16355 
16356 static PyMethodDef AuthorityInfoAccess_methods[] = {
16357     {"format_lines", (PyCFunction)AuthorityInfoAccess_format_lines,   METH_VARARGS|METH_KEYWORDS, generic_format_lines_doc},
16358     {"format",       (PyCFunction)AuthorityInfoAccess_format,         METH_VARARGS|METH_KEYWORDS, generic_format_doc},
16359     {NULL, NULL}  /* Sentinel */
16360 };
16361 
16362 /* =========================== Class Construction =========================== */
16363 
16364 static PyObject *
AuthorityInfoAccess_new(PyTypeObject * type,PyObject * args,PyObject * kwds)16365 AuthorityInfoAccess_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
16366 {
16367     AuthorityInfoAccess *self;
16368 
16369     TraceObjNewEnter(type);
16370 
16371     if ((self = (AuthorityInfoAccess *)type->tp_alloc(type, 0)) == NULL) {
16372         return NULL;
16373     }
16374 
16375     if ((self->arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE)) == NULL) {
16376         type->tp_free(self);
16377         return set_nspr_error(NULL);
16378     }
16379 
16380     self->aia = NULL;
16381 
16382     TraceObjNewLeave(self);
16383     return (PyObject *)self;
16384 }
16385 
16386 
16387 static void
AuthorityInfoAccess_dealloc(AuthorityInfoAccess * self)16388 AuthorityInfoAccess_dealloc(AuthorityInfoAccess* self)
16389 {
16390     TraceMethodEnter(self);
16391 
16392     PORT_FreeArena(self->arena, PR_FALSE);
16393     Py_TYPE(self)->tp_free((PyObject*)self);
16394 }
16395 
16396 PyDoc_STRVAR(AuthorityInfoAccess_doc,
16397 "AuthorityInfoAccess()\n\
16398 \n\
16399 An object representing AuthorityInfoAccess.\n\
16400 ");
16401 
16402 static int
AuthorityInfoAccess_init(AuthorityInfoAccess * self,PyObject * args,PyObject * kwds)16403 AuthorityInfoAccess_init(AuthorityInfoAccess *self, PyObject *args, PyObject *kwds)
16404 {
16405     static char *kwlist[] = {NULL};
16406 
16407     TraceMethodEnter(self);
16408 
16409     if (!PyArg_ParseTupleAndKeywords(args, kwds, ":AuthorityInfoAccess", kwlist
16410                                      ))
16411         return -1;
16412 
16413     return 0;
16414 }
16415 
16416 static PyTypeObject AuthorityInfoAccessType = {
16417     PyVarObject_HEAD_INIT(NULL, 0)
16418     "nss.nss.AuthorityInfoAccess",		/* tp_name */
16419     sizeof(AuthorityInfoAccess),		/* tp_basicsize */
16420     0,						/* tp_itemsize */
16421     (destructor)AuthorityInfoAccess_dealloc,	/* tp_dealloc */
16422     0,						/* tp_print */
16423     0,						/* tp_getattr */
16424     0,						/* tp_setattr */
16425     0,						/* tp_compare */
16426     0,						/* tp_repr */
16427     0,						/* tp_as_number */
16428     0,						/* tp_as_sequence */
16429     0,						/* tp_as_mapping */
16430     0,						/* tp_hash */
16431     0,						/* tp_call */
16432     (reprfunc)AuthorityInfoAccess_str,		/* tp_str */
16433     0,						/* tp_getattro */
16434     0,						/* tp_setattro */
16435     0,						/* tp_as_buffer */
16436     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,	/* tp_flags */
16437     AuthorityInfoAccess_doc,			/* tp_doc */
16438     (traverseproc)0,				/* tp_traverse */
16439     (inquiry)0,					/* tp_clear */
16440     0,						/* tp_richcompare */
16441     0,						/* tp_weaklistoffset */
16442     0,						/* tp_iter */
16443     0,						/* tp_iternext */
16444     AuthorityInfoAccess_methods,		/* tp_methods */
16445     AuthorityInfoAccess_members,		/* tp_members */
16446     AuthorityInfoAccess_getseters,		/* tp_getset */
16447     0,						/* tp_base */
16448     0,						/* tp_dict */
16449     0,						/* tp_descr_get */
16450     0,						/* tp_descr_set */
16451     0,						/* tp_dictoffset */
16452     (initproc)AuthorityInfoAccess_init,		/* tp_init */
16453     0,						/* tp_alloc */
16454     AuthorityInfoAccess_new,			/* tp_new */
16455 };
16456 
16457 static PyObject *
AuthorityInfoAccess_new_from_CERTAuthInfoAccess(CERTAuthInfoAccess * aia)16458 AuthorityInfoAccess_new_from_CERTAuthInfoAccess(CERTAuthInfoAccess *aia)
16459 {
16460     AuthorityInfoAccess *self = NULL;
16461 
16462     TraceObjNewEnter(NULL);
16463 
16464     if ((self = (AuthorityInfoAccess *) AuthorityInfoAccessType.tp_new(&AuthorityInfoAccessType, NULL, NULL)) == NULL) {
16465         return NULL;
16466     }
16467 
16468     if (CERT_CopyAuthInfoAccess(self->arena, &self->aia, aia) != SECSuccess) {
16469         set_nspr_error(NULL);
16470         Py_CLEAR(self);
16471         return NULL;
16472     }
16473 
16474     TraceObjNewLeave(self);
16475     return (PyObject *) self;
16476 }
16477 /* ========================================================================== */
16478 /* ======================= AuthorityInfoAccesses Class ====================== */
16479 /* ========================================================================== */
16480 
16481 /* ============================ Attribute Access ============================ */
16482 
16483 /* ============================== Class Methods ============================= */
16484 
16485 static PyObject *
AuthorityInfoAccesses_format_lines(AuthorityInfoAccesses * self,PyObject * args,PyObject * kwds)16486 AuthorityInfoAccesses_format_lines(AuthorityInfoAccesses *self, PyObject *args, PyObject *kwds)
16487 {
16488     static char *kwlist[] = {"level", NULL};
16489     int level = 0;
16490     PyObject *lines = NULL;
16491     PyObject *obj = NULL;
16492     Py_ssize_t len, i;
16493 
16494     TraceMethodEnter(self);
16495 
16496     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:format_lines", kwlist, &level))
16497         return NULL;
16498 
16499     if ((lines = PyList_New(0)) == NULL) {
16500         return NULL;
16501     }
16502 
16503     len = PyObject_Size((PyObject *)self);
16504     if ((obj = PyUnicode_FromFormat("Authority Information Access: [%zd total]", len)) == NULL) {
16505         goto fail;
16506     }
16507     FMT_OBJ_AND_APPEND(lines, NULL, obj, level, fail);
16508     Py_CLEAR(obj);
16509 
16510 
16511     for (i = 0; i < len; i++) {
16512         if ((obj = PyUnicode_FromFormat("Info [%zd]:", i+1)) == NULL) {
16513             goto fail;
16514         }
16515         FMT_OBJ_AND_APPEND(lines, NULL, obj, level+1, fail);
16516         Py_CLEAR(obj);
16517         if ((obj = PySequence_GetItem((PyObject *)self, i)) == NULL) {
16518             goto fail;
16519         }
16520         CALL_FORMAT_LINES_AND_APPEND(lines, obj, level+2, fail);
16521         Py_CLEAR(obj);
16522     }
16523 
16524     return lines;
16525 
16526  fail:
16527     Py_XDECREF(obj);
16528     Py_XDECREF(lines);
16529     return NULL;
16530 }
16531 
16532 static PyObject *
AuthorityInfoAccesses_format(AuthorityInfoAccesses * self,PyObject * args,PyObject * kwds)16533 AuthorityInfoAccesses_format(AuthorityInfoAccesses *self, PyObject *args, PyObject *kwds)
16534 {
16535     TraceMethodEnter(self);
16536 
16537     return format_from_lines((format_lines_func)AuthorityInfoAccesses_format_lines, (PyObject *)self, args, kwds);
16538 }
16539 
16540 static PyObject *
AuthorityInfoAccesses_str(AuthorityInfoAccesses * self)16541 AuthorityInfoAccesses_str(AuthorityInfoAccesses *self)
16542 {
16543     PyObject *py_formatted_result = NULL;
16544 
16545     TraceMethodEnter(self);
16546 
16547     py_formatted_result =  AuthorityInfoAccesses_format(self, empty_tuple, NULL);
16548     return py_formatted_result;
16549 
16550 }
16551 
16552 
16553 static PyMethodDef AuthorityInfoAccesses_methods[] = {
16554     {"format_lines", (PyCFunction)AuthorityInfoAccesses_format_lines,   METH_VARARGS|METH_KEYWORDS, generic_format_lines_doc},
16555     {"format",       (PyCFunction)AuthorityInfoAccesses_format,         METH_VARARGS|METH_KEYWORDS, generic_format_doc},
16556     {NULL, NULL}  /* Sentinel */
16557 };
16558 
16559 /* =========================== Sequence Protocol ============================ */
16560 static Py_ssize_t
CERTAuthInfoAccess_count(CERTAuthInfoAccess ** aias)16561 CERTAuthInfoAccess_count(CERTAuthInfoAccess **aias)
16562 {
16563     CERTAuthInfoAccess **cur;
16564     Py_ssize_t count;
16565 
16566     if (aias == NULL) {
16567         return 0;
16568     }
16569 
16570     for (count = 0, cur = aias; *cur; cur++, count++);
16571 
16572     return count;
16573 }
16574 
16575 static Py_ssize_t
AuthorityInfoAccesses_length(AuthorityInfoAccesses * self)16576 AuthorityInfoAccesses_length(AuthorityInfoAccesses *self)
16577 {
16578     if (!self->py_aias) return 0;
16579     return PyTuple_Size(self->py_aias);
16580 }
16581 
16582 static PyObject *
AuthorityInfoAccesses_item(AuthorityInfoAccesses * self,register Py_ssize_t i)16583 AuthorityInfoAccesses_item(AuthorityInfoAccesses *self, register Py_ssize_t i)
16584 {
16585     PyObject *py_aia = NULL;
16586 
16587     if (!self->py_aias) {
16588         return PyErr_Format(PyExc_ValueError, "%s is uninitialized", Py_TYPE(self)->tp_name);
16589     }
16590 
16591     py_aia = PyTuple_GetItem(self->py_aias, i);
16592     Py_XINCREF(py_aia);
16593     return py_aia;
16594 }
16595 
16596 
16597 /* =========================== Class Construction =========================== */
16598 
16599 static int
AuthorityInfoAccesses_init_from_SECItem(AuthorityInfoAccesses * self,SECItem * item)16600 AuthorityInfoAccesses_init_from_SECItem(AuthorityInfoAccesses *self, SECItem *item)
16601 {
16602     CERTAuthInfoAccess **aias;
16603     PLArenaPool *arena;
16604     Py_ssize_t count, i;
16605     PyObject *py_aias = NULL;
16606 
16607     Py_CLEAR(self->py_aias);
16608 
16609     if ((arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE)) == NULL) {
16610         return -1;
16611     }
16612 
16613     if ((aias = CERT_DecodeAuthInfoAccessExtension(arena, item)) == NULL) {
16614         set_nspr_error("cannot decode Authority Access Info extension");
16615         PORT_FreeArena(arena, PR_FALSE);
16616         return -1;
16617     }
16618 
16619     count = CERTAuthInfoAccess_count(aias);
16620 
16621     if ((py_aias = PyTuple_New(count)) == NULL) {
16622         PORT_FreeArena(arena, PR_FALSE);
16623 	return -1;
16624     }
16625 
16626     for (i = 0; i < count; i++) {
16627         PyObject *py_aia;
16628 
16629         if ((py_aia = AuthorityInfoAccess_new_from_CERTAuthInfoAccess(aias[i])) == NULL) {
16630             PORT_FreeArena(arena, PR_FALSE);
16631             Py_CLEAR(py_aias);
16632             return -1;
16633         }
16634 
16635         PyTuple_SetItem(py_aias, i, py_aia);
16636     }
16637 
16638     ASSIGN_NEW_REF(self->py_aias, py_aias);
16639 
16640     PORT_FreeArena(arena, PR_FALSE);
16641 
16642     return 0;
16643 }
16644 
16645 static PyObject *
AuthorityInfoAccesses_new(PyTypeObject * type,PyObject * args,PyObject * kwds)16646 AuthorityInfoAccesses_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
16647 {
16648     AuthorityInfoAccesses *self;
16649 
16650     TraceObjNewEnter(type);
16651 
16652     if ((self = (AuthorityInfoAccesses *)type->tp_alloc(type, 0)) == NULL) {
16653         return NULL;
16654     }
16655 
16656     self->py_aias = NULL;
16657 
16658     TraceObjNewLeave(self);
16659     return (PyObject *)self;
16660 }
16661 
16662 static int
AuthorityInfoAccesses_traverse(AuthorityInfoAccesses * self,visitproc visit,void * arg)16663 AuthorityInfoAccesses_traverse(AuthorityInfoAccesses *self, visitproc visit, void *arg)
16664 {
16665     TraceMethodEnter(self);
16666 
16667     Py_VISIT(self->py_aias);
16668     return 0;
16669 }
16670 
16671 static int
AuthorityInfoAccesses_clear(AuthorityInfoAccesses * self)16672 AuthorityInfoAccesses_clear(AuthorityInfoAccesses* self)
16673 {
16674     TraceMethodEnter(self);
16675 
16676     Py_CLEAR(self->py_aias);
16677     return 0;
16678 }
16679 
16680 static void
AuthorityInfoAccesses_dealloc(AuthorityInfoAccesses * self)16681 AuthorityInfoAccesses_dealloc(AuthorityInfoAccesses* self)
16682 {
16683     TraceMethodEnter(self);
16684 
16685     AuthorityInfoAccesses_clear(self);
16686 
16687     Py_TYPE(self)->tp_free((PyObject*)self);
16688 }
16689 
16690 PyDoc_STRVAR(AuthorityInfoAccesses_doc,
16691 "AuthorityInfoAccesses(data)\n\
16692 \n\
16693 :Parameters:\n\
16694     data : SecItem or str or any buffer compatible object\n\
16695         Data to initialize the Authority Information Access\n\
16696         from, must be in DER format\n\
16697 \n\
16698 An object representing AuthorityInfoAccess Extension.\n\
16699 ");
16700 
16701 static int
AuthorityInfoAccesses_init(AuthorityInfoAccesses * self,PyObject * args,PyObject * kwds)16702 AuthorityInfoAccesses_init(AuthorityInfoAccesses *self, PyObject *args, PyObject *kwds)
16703 {
16704     static char *kwlist[] = {"auth_info_accesses", NULL};
16705     SECItem_param *data_param = NULL;
16706     int result = 0;
16707 
16708     TraceMethodEnter(self);
16709 
16710     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&:AuthorityInfoAccesses", kwlist,
16711                                      SECItemConvert, &data_param))
16712         return -1;
16713 
16714     result = AuthorityInfoAccesses_init_from_SECItem(self, &data_param->item);
16715     SECItem_param_release(data_param);
16716     return result;
16717 }
16718 
16719 static PySequenceMethods AuthorityInfoAccesses_as_sequence = {
16720     (lenfunc)AuthorityInfoAccesses_length,	/* sq_length */
16721     0,						/* sq_concat */
16722     0,						/* sq_repeat */
16723     (ssizeargfunc)AuthorityInfoAccesses_item,	/* sq_item */
16724     0,						/* sq_slice */
16725     0,						/* sq_ass_item */
16726     0,						/* sq_ass_slice */
16727     0,						/* sq_contains */
16728     0,						/* sq_inplace_concat */
16729     0,						/* sq_inplace_repeat */
16730 };
16731 
16732 static PyTypeObject AuthorityInfoAccessesType = {
16733     PyVarObject_HEAD_INIT(NULL, 0)
16734     "nss.nss.AuthorityInfoAccesses",		/* tp_name */
16735     sizeof(AuthorityInfoAccesses),		/* tp_basicsize */
16736     0,						/* tp_itemsize */
16737     (destructor)AuthorityInfoAccesses_dealloc,	/* tp_dealloc */
16738     0,						/* tp_print */
16739     0,						/* tp_getattr */
16740     0,						/* tp_setattr */
16741     0,						/* tp_compare */
16742     0,						/* tp_repr */
16743     0,						/* tp_as_number */
16744     &AuthorityInfoAccesses_as_sequence,		/* tp_as_sequence */
16745     0,						/* tp_as_mapping */
16746     0,						/* tp_hash */
16747     0,						/* tp_call */
16748     (reprfunc)AuthorityInfoAccesses_str,	/* tp_str */
16749     0,						/* tp_getattro */
16750     0,						/* tp_setattro */
16751     0,						/* tp_as_buffer */
16752     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,	/* tp_flags */
16753     AuthorityInfoAccesses_doc,			/* tp_doc */
16754     (traverseproc)AuthorityInfoAccesses_traverse,	/* tp_traverse */
16755     (inquiry)AuthorityInfoAccesses_clear,	/* tp_clear */
16756     0,						/* tp_richcompare */
16757     0,						/* tp_weaklistoffset */
16758     0,						/* tp_iter */
16759     0,						/* tp_iternext */
16760     AuthorityInfoAccesses_methods,		/* tp_methods */
16761     0,						/* tp_members */
16762     0,						/* tp_getset */
16763     0,						/* tp_base */
16764     0,						/* tp_dict */
16765     0,						/* tp_descr_get */
16766     0,						/* tp_descr_set */
16767     0,						/* tp_dictoffset */
16768     (initproc)AuthorityInfoAccesses_init,	/* tp_init */
16769     0,						/* tp_alloc */
16770     AuthorityInfoAccesses_new,			/* tp_new */
16771 };
16772 
16773 PyObject *
AuthorityInfoAccesses_new_from_SECItem(SECItem * item)16774 AuthorityInfoAccesses_new_from_SECItem(SECItem *item)
16775 {
16776     AuthorityInfoAccesses *self = NULL;
16777 
16778     TraceObjNewEnter(NULL);
16779 
16780     if ((self = (AuthorityInfoAccesses *) AuthorityInfoAccessesType.tp_new(&AuthorityInfoAccessesType, NULL, NULL)) == NULL) {
16781         return NULL;
16782     }
16783 
16784     if (AuthorityInfoAccesses_init_from_SECItem(self, item) < 0) {
16785         Py_CLEAR(self);
16786         return NULL;
16787     }
16788 
16789     TraceObjNewLeave(self);
16790     return (PyObject *) self;
16791 }
16792 
16793 /* ========================================================================== */
16794 /* ============================ AuthKeyID Class ============================= */
16795 /* ========================================================================== */
16796 
16797 /* ============================ Attribute Access ============================ */
16798 
16799 static PyObject *
AuthKeyID_get_key_id(AuthKeyID * self,void * closure)16800 AuthKeyID_get_key_id(AuthKeyID *self, void *closure)
16801 {
16802     TraceMethodEnter(self);
16803 
16804     if (!self->auth_key_id) {
16805         return PyErr_Format(PyExc_ValueError, "%s is uninitialized", Py_TYPE(self)->tp_name);
16806     }
16807 
16808     if (!self->auth_key_id->keyID.len || !self->auth_key_id->keyID.data) {
16809         Py_RETURN_NONE;
16810     }
16811 
16812     return SecItem_new_from_SECItem(&self->auth_key_id->keyID, SECITEM_unknown);
16813 }
16814 
16815 static PyObject *
AuthKeyID_get_serial_number(AuthKeyID * self,void * closure)16816 AuthKeyID_get_serial_number(AuthKeyID *self, void *closure)
16817 {
16818     TraceMethodEnter(self);
16819 
16820     if (!self->auth_key_id) {
16821         return PyErr_Format(PyExc_ValueError, "%s is uninitialized", Py_TYPE(self)->tp_name);
16822     }
16823 
16824     if (!self->auth_key_id->authCertSerialNumber.len || !self->auth_key_id->authCertSerialNumber.data) {
16825         Py_RETURN_NONE;
16826     }
16827 
16828     return integer_secitem_to_pylong(&self->auth_key_id->authCertSerialNumber);
16829 }
16830 
16831 static
16832 PyGetSetDef AuthKeyID_getseters[] = {
16833     {"key_id", (getter)AuthKeyID_get_key_id,    (setter)NULL,
16834      "Returns the key id as a SecItem", NULL},
16835     {"serial_number", (getter)AuthKeyID_get_serial_number,    (setter)NULL,
16836      "Returns the key id as a SecItem", NULL},
16837     {NULL}  /* Sentinel */
16838 };
16839 
16840 static PyMemberDef AuthKeyID_members[] = {
16841     {NULL}  /* Sentinel */
16842 };
16843 
16844 /* ============================== Class Methods ============================= */
16845 
16846 PyDoc_STRVAR(AuthKeyID_get_general_names_doc,
16847 "get_general_names(repr_kind=AsString) -> (general_name, ...)\n\
16848 \n\
16849 :Parameters:\n\
16850     repr_kind : RepresentationKind constant\n\
16851         Specifies what the contents of the returned tuple will be.\n\
16852         May be one of:\n\
16853 \n\
16854         AsObject\n\
16855             The general name as a nss.GeneralName object\n\
16856         AsString\n\
16857             The general name as a string.\n\
16858             (e.g. \"http://crl.geotrust.com/crls/secureca.crl\")\n\
16859         AsTypeString\n\
16860             The general name type as a string.\n\
16861              (e.g. \"URI\")\n\
16862         AsTypeEnum\n\
16863             The general name type as a general name type enumerated constant.\n\
16864              (e.g. nss.certURI )\n\
16865         AsLabeledString\n\
16866             The general name as a string with it's type prepended.\n\
16867             (e.g. \"URI: http://crl.geotrust.com/crls/secureca.crl\"\n\
16868 \n\
16869 Returns a tuple of general names in the authentication key id extension\n\
16870 for the issuer. If the issuer was not defined then the returned tuple\n\
16871 will be empty.\n\
16872 \n\
16873 You may specify how the each member of the tuple is represented, by default\n\
16874 it will be as a string.\n\
16875 ");
16876 
16877 static PyObject *
AuthKeyID_get_general_names(AuthKeyID * self,PyObject * args,PyObject * kwds)16878 AuthKeyID_get_general_names(AuthKeyID *self, PyObject *args, PyObject *kwds)
16879 {
16880     static char *kwlist[] = {"repr_kind", NULL};
16881     int repr_kind = AsString;
16882 
16883     TraceMethodEnter(self);
16884 
16885     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:get_general_names", kwlist,
16886                                      &repr_kind))
16887         return NULL;
16888 
16889     if (!self->auth_key_id) {
16890         return PyErr_Format(PyExc_ValueError, "%s is uninitialized", Py_TYPE(self)->tp_name);
16891     }
16892 
16893     return AuthKeyID_general_names_tuple(self, repr_kind);
16894 }
16895 
16896 static PyObject *
AuthKeyID_format_lines(AuthKeyID * self,PyObject * args,PyObject * kwds)16897 AuthKeyID_format_lines(AuthKeyID *self, PyObject *args, PyObject *kwds)
16898 {
16899     static char *kwlist[] = {"level", NULL};
16900     int level = 0;
16901     Py_ssize_t len;
16902     PyObject *lines = NULL;
16903     PyObject *obj = NULL;
16904     PyObject *obj1 = NULL;
16905 
16906     TraceMethodEnter(self);
16907 
16908     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:format_lines", kwlist, &level))
16909         return NULL;
16910 
16911     if ((lines = PyList_New(0)) == NULL) {
16912         return NULL;
16913     }
16914 
16915     if (!self->auth_key_id) {
16916         return lines;
16917     }
16918 
16919     FMT_LABEL_AND_APPEND(lines, _("Key ID"), level, fail);
16920 
16921     if ((obj = AuthKeyID_get_key_id(self, NULL)) == NULL) {
16922         goto fail;
16923     }
16924     APPEND_OBJ_TO_HEX_LINES_AND_CLEAR(lines, obj, level+1, fail);
16925 
16926     if ((obj = AuthKeyID_get_serial_number(self, NULL)) == NULL) {
16927         goto fail;
16928     }
16929 
16930     if ((obj1 = PyObject_String(obj)) == NULL) {
16931         goto fail;
16932     }
16933     Py_CLEAR(obj);
16934 
16935     FMT_OBJ_AND_APPEND(lines, _("Serial Number"), obj1, level, fail);
16936     Py_CLEAR(obj1);
16937 
16938     if ((obj = AuthKeyID_general_names_tuple(self, AsString)) == NULL) {
16939         goto fail;
16940     }
16941     len = PyObject_Size(obj);
16942     if ((obj1 = PyUnicode_FromFormat("General Names: [%zd total]", len)) == NULL) {
16943         goto fail;
16944     }
16945     FMT_OBJ_AND_APPEND(lines, NULL, obj1, level, fail);
16946     Py_CLEAR(obj1);
16947 
16948     APPEND_LINES_AND_CLEAR(lines, obj, level+1, fail);
16949 
16950     return lines;
16951 
16952  fail:
16953     Py_XDECREF(obj);
16954     Py_XDECREF(obj1);
16955     Py_XDECREF(lines);
16956     return NULL;
16957 }
16958 
16959 static PyObject *
AuthKeyID_format(AuthKeyID * self,PyObject * args,PyObject * kwds)16960 AuthKeyID_format(AuthKeyID *self, PyObject *args, PyObject *kwds)
16961 {
16962     TraceMethodEnter(self);
16963 
16964     return format_from_lines((format_lines_func)AuthKeyID_format_lines, (PyObject *)self, args, kwds);
16965 }
16966 
16967 static PyObject *
AuthKeyID_str(AuthKeyID * self)16968 AuthKeyID_str(AuthKeyID *self)
16969 {
16970     PyObject *py_formatted_result = NULL;
16971 
16972     TraceMethodEnter(self);
16973 
16974     py_formatted_result =  AuthKeyID_format(self, empty_tuple, NULL);
16975     return py_formatted_result;
16976 
16977 }
16978 
16979 
16980 static PyMethodDef AuthKeyID_methods[] = {
16981     {"format_lines",      (PyCFunction)AuthKeyID_format_lines,      METH_VARARGS|METH_KEYWORDS, generic_format_lines_doc},
16982     {"format",            (PyCFunction)AuthKeyID_format,            METH_VARARGS|METH_KEYWORDS, generic_format_doc},
16983     {"get_general_names", (PyCFunction)AuthKeyID_get_general_names, METH_VARARGS|METH_KEYWORDS, AuthKeyID_get_general_names_doc},
16984     {NULL, NULL}  /* Sentinel */
16985 };
16986 
16987 /* =========================== Class Construction =========================== */
16988 
16989 static PyObject *
AuthKeyID_new(PyTypeObject * type,PyObject * args,PyObject * kwds)16990 AuthKeyID_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
16991 {
16992     AuthKeyID *self;
16993 
16994     TraceObjNewEnter(type);
16995 
16996     if ((self = (AuthKeyID *)type->tp_alloc(type, 0)) == NULL) {
16997         return NULL;
16998     }
16999 
17000     if ((self->arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE)) == NULL) {
17001         type->tp_free(self);
17002         return set_nspr_error(NULL);
17003     }
17004 
17005     self->auth_key_id = NULL;
17006 
17007     TraceObjNewLeave(self);
17008     return (PyObject *)self;
17009 }
17010 
17011 static void
AuthKeyID_dealloc(AuthKeyID * self)17012 AuthKeyID_dealloc(AuthKeyID* self)
17013 {
17014     TraceMethodEnter(self);
17015 
17016     if (self->arena) {
17017         PORT_FreeArena(self->arena, PR_FALSE);
17018     }
17019 
17020     Py_TYPE(self)->tp_free((PyObject*)self);
17021 }
17022 
17023 PyDoc_STRVAR(AuthKeyID_doc,
17024 "An object representing Authentication Key ID extension");
17025 
17026 static int
AuthKeyID_init(AuthKeyID * self,PyObject * args,PyObject * kwds)17027 AuthKeyID_init(AuthKeyID *self, PyObject *args, PyObject *kwds)
17028 {
17029     static char *kwlist[] = {"auth_key_id", NULL};
17030     SecItem *py_sec_item;
17031 
17032     TraceMethodEnter(self);
17033 
17034     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!:AuthKeyID", kwlist,
17035                                      &SecItemType, &py_sec_item))
17036         return -1;
17037 
17038     if ((self->auth_key_id = CERT_DecodeAuthKeyID(self->arena, &py_sec_item->item)) == NULL) {
17039         set_nspr_error("cannot decode AuthKeyID");
17040         return -1;
17041     }
17042 
17043     return 0;
17044 }
17045 
17046 static Py_ssize_t
AuthKeyID_general_names_count(AuthKeyID * self)17047 AuthKeyID_general_names_count(AuthKeyID *self)
17048 {
17049     if (!self->auth_key_id || !self->auth_key_id->authCertIssuer) {
17050         return 0;
17051     }
17052 
17053     return CERTGeneralName_list_count(self->auth_key_id->authCertIssuer);
17054 }
17055 
17056 static PyObject *
AuthKeyID_general_names_tuple(AuthKeyID * self,RepresentationKind repr_kind)17057 AuthKeyID_general_names_tuple(AuthKeyID *self, RepresentationKind repr_kind)
17058 {
17059     Py_ssize_t n_names;
17060 
17061     n_names = AuthKeyID_general_names_count(self);
17062 
17063     if (n_names == 0) {
17064         Py_INCREF(empty_tuple);
17065         return empty_tuple;
17066     }
17067 
17068     return CERTGeneralName_list_to_tuple(self->auth_key_id->authCertIssuer, repr_kind);
17069 }
17070 
17071 static PyObject *
AuthKeyID_repr(AuthKeyID * self)17072 AuthKeyID_repr(AuthKeyID *self)
17073 {
17074     PyObject *result = NULL;
17075     PyObject *sep = NULL;
17076     PyObject *names = NULL;
17077     PyObject *name_str = NULL;
17078     PyObject *key_id = NULL;
17079     PyObject *key_id_str = NULL;
17080     PyObject *serial_number = NULL;
17081     PyObject *serial_number_str = NULL;
17082 
17083     if (!self->auth_key_id) {
17084         return PyUnicode_FromFormat("<%s object at %p>",
17085                                     Py_TYPE(self)->tp_name, self);
17086     }
17087 
17088     if ((sep = PyUnicode_FromString(", ")) == NULL) {
17089         goto exit;
17090     }
17091 
17092     if ((names = AuthKeyID_general_names_tuple(self, AsString)) == NULL) {
17093         goto exit;
17094     }
17095 
17096     /* Paste them all together with ", " between. */
17097     if ((name_str = PyUnicode_Join(sep, names)) == NULL) {
17098         goto exit;
17099     }
17100 
17101     if ((key_id = AuthKeyID_get_key_id(self, NULL)) == NULL) {
17102         goto exit;
17103     }
17104 
17105     if ((key_id_str = PyObject_String(key_id)) == NULL) {
17106         goto exit;
17107     }
17108 
17109     if ((serial_number = AuthKeyID_get_serial_number(self, NULL)) == NULL) {
17110         goto exit;
17111     }
17112 
17113     if ((serial_number_str = PyObject_String(serial_number)) == NULL) {
17114         goto exit;
17115     }
17116 
17117     result = PyUnicode_FromFormat("ID: %U, Serial Number: %U, Issuer: [%U]",
17118                                   key_id_str, serial_number_str, name_str);
17119 
17120 
17121     exit:
17122     Py_XDECREF(sep);
17123     Py_XDECREF(names);
17124     Py_XDECREF(name_str);
17125     Py_XDECREF(key_id);
17126     Py_XDECREF(key_id_str);
17127     Py_XDECREF(serial_number);
17128     Py_XDECREF(serial_number_str);
17129     return result;
17130 }
17131 
17132 static PyTypeObject AuthKeyIDType = {
17133     PyVarObject_HEAD_INIT(NULL, 0)
17134     "nss.nss.AuthKeyID",			/* tp_name */
17135     sizeof(AuthKeyID),				/* tp_basicsize */
17136     0,						/* tp_itemsize */
17137     (destructor)AuthKeyID_dealloc,		/* tp_dealloc */
17138     0,						/* tp_print */
17139     0,						/* tp_getattr */
17140     0,						/* tp_setattr */
17141     0,						/* tp_compare */
17142     (reprfunc)AuthKeyID_repr,			/* tp_repr */
17143     0,						/* tp_as_number */
17144     0,						/* tp_as_sequence */
17145     0,						/* tp_as_mapping */
17146     0,						/* tp_hash */
17147     0,						/* tp_call */
17148     (reprfunc)AuthKeyID_str,			/* tp_str */
17149     0,						/* tp_getattro */
17150     0,						/* tp_setattro */
17151     0,						/* tp_as_buffer */
17152     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,	/* tp_flags */
17153     AuthKeyID_doc,				/* tp_doc */
17154     0,						/* tp_traverse */
17155     0,						/* tp_clear */
17156     0,						/* tp_richcompare */
17157     0,						/* tp_weaklistoffset */
17158     0,						/* tp_iter */
17159     0,						/* tp_iternext */
17160     AuthKeyID_methods,				/* tp_methods */
17161     AuthKeyID_members,				/* tp_members */
17162     AuthKeyID_getseters,			/* tp_getset */
17163     0,						/* tp_base */
17164     0,						/* tp_dict */
17165     0,						/* tp_descr_get */
17166     0,						/* tp_descr_set */
17167     0,						/* tp_dictoffset */
17168     (initproc)AuthKeyID_init,			/* tp_init */
17169     0,						/* tp_alloc */
17170     AuthKeyID_new,				/* tp_new */
17171 };
17172 
17173 PyObject *
AuthKeyID_new_from_CERTAuthKeyID(CERTAuthKeyID * auth_key_id)17174 AuthKeyID_new_from_CERTAuthKeyID(CERTAuthKeyID *auth_key_id)
17175 {
17176     AuthKeyID *self = NULL;
17177 
17178     TraceObjNewEnter(NULL);
17179 
17180     if ((self = (AuthKeyID *) AuthKeyIDType.tp_new(&AuthKeyIDType, NULL, NULL)) == NULL) {
17181         return NULL;
17182     }
17183 
17184     if (CERT_CopyAuthKeyID(self->arena, &self->auth_key_id, auth_key_id) != SECSuccess) {
17185         set_nspr_error(NULL);
17186         Py_CLEAR(self);
17187         return NULL;
17188     }
17189 
17190     TraceObjNewLeave(self);
17191     return (PyObject *) self;
17192 }
17193 
17194 PyObject *
AuthKeyID_new_from_SECItem(SECItem * item)17195 AuthKeyID_new_from_SECItem(SECItem *item)
17196 {
17197     AuthKeyID *self = NULL;
17198 
17199     TraceObjNewEnter(NULL);
17200 
17201     if ((self = (AuthKeyID *) AuthKeyIDType.tp_new(&AuthKeyIDType, NULL, NULL)) == NULL) {
17202         return NULL;
17203     }
17204 
17205     if ((self->auth_key_id = CERT_DecodeAuthKeyID(self->arena, item)) == NULL) {
17206         set_nspr_error("cannot decode AuthKeyID");
17207         Py_CLEAR(self);
17208         return NULL;
17209     }
17210 
17211     TraceObjNewLeave(self);
17212     return (PyObject *) self;
17213 }
17214 
17215 
17216 
17217 /* ========================================================================== */
17218 /* ======================== BasicConstraints Class ========================== */
17219 /* ========================================================================== */
17220 
17221 /* ============================ Attribute Access ============================ */
17222 
17223 static PyObject *
BasicConstraints_get_is_ca(BasicConstraints * self,void * closure)17224 BasicConstraints_get_is_ca(BasicConstraints *self, void *closure)
17225 {
17226     TraceMethodEnter(self);
17227 
17228     return PyBool_FromLong(self->bc.isCA);
17229 
17230     return NULL;
17231 }
17232 
17233 static PyObject *
BasicConstraints_get_path_len(BasicConstraints * self,void * closure)17234 BasicConstraints_get_path_len(BasicConstraints *self, void *closure)
17235 {
17236     TraceMethodEnter(self);
17237 
17238     return PyLong_FromLong(self->bc.pathLenConstraint);
17239 
17240     return NULL;
17241 }
17242 
17243 static
17244 PyGetSetDef BasicConstraints_getseters[] = {
17245     {"is_ca", (getter)BasicConstraints_get_is_ca,    (setter)NULL,
17246      "returns boolean, True if certificate is a certificate authority (i.e. CA)", NULL},
17247     {"path_len", (getter)BasicConstraints_get_path_len,    (setter)NULL,
17248      "returns max path length constraint as an integer", NULL},
17249     {NULL}  /* Sentinel */
17250 };
17251 
17252 static PyMemberDef BasicConstraints_members[] = {
17253     {NULL}  /* Sentinel */
17254 };
17255 
17256 /* ============================== Class Methods ============================= */
17257 
17258 static PyObject *
BasicConstraints_format_lines(BasicConstraints * self,PyObject * args,PyObject * kwds)17259 BasicConstraints_format_lines(BasicConstraints *self, PyObject *args, PyObject *kwds)
17260 {
17261     static char *kwlist[] = {"level", NULL};
17262     int level = 0;
17263     PyObject *lines = NULL;
17264     PyObject *obj = NULL;
17265 
17266     TraceMethodEnter(self);
17267 
17268     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:format_lines", kwlist, &level))
17269         return NULL;
17270 
17271     if ((lines = PyList_New(0)) == NULL) {
17272         return NULL;
17273     }
17274 
17275     obj = self->bc.isCA ? Py_True : Py_False;
17276     Py_INCREF(obj);
17277     FMT_OBJ_AND_APPEND(lines, _("Is CA"), obj, level, fail);
17278     Py_CLEAR(obj);
17279 
17280     if ((obj = PyUnicode_FromFormat("%d", self->bc.pathLenConstraint)) == NULL) {
17281         goto fail;
17282     }
17283     FMT_OBJ_AND_APPEND(lines, _("Path Length"), obj, level, fail);
17284     Py_CLEAR(obj);
17285 
17286     return lines;
17287 
17288  fail:
17289     Py_XDECREF(obj);
17290     Py_XDECREF(lines);
17291     return NULL;
17292 }
17293 
17294 static PyObject *
BasicConstraints_format(BasicConstraints * self,PyObject * args,PyObject * kwds)17295 BasicConstraints_format(BasicConstraints *self, PyObject *args, PyObject *kwds)
17296 {
17297     TraceMethodEnter(self);
17298 
17299     return format_from_lines((format_lines_func)BasicConstraints_format_lines, (PyObject *)self, args, kwds);
17300 }
17301 
17302 static PyMethodDef BasicConstraints_methods[] = {
17303     {"format_lines", (PyCFunction)BasicConstraints_format_lines,   METH_VARARGS|METH_KEYWORDS, generic_format_lines_doc},
17304     {"format",       (PyCFunction)BasicConstraints_format,         METH_VARARGS|METH_KEYWORDS, generic_format_doc},
17305     {NULL, NULL}  /* Sentinel */
17306 };
17307 
17308 /* =========================== Class Construction =========================== */
17309 
17310 static PyObject *
BasicConstraints_new(PyTypeObject * type,PyObject * args,PyObject * kwds)17311 BasicConstraints_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
17312 {
17313     BasicConstraints *self;
17314 
17315     TraceObjNewEnter(type);
17316 
17317     if ((self = (BasicConstraints *)type->tp_alloc(type, 0)) == NULL) {
17318         return NULL;
17319     }
17320 
17321     memset(&self->bc, 0, sizeof(self->bc));
17322 
17323 
17324     TraceObjNewLeave(self);
17325     return (PyObject *)self;
17326 }
17327 
17328 static void
BasicConstraints_dealloc(BasicConstraints * self)17329 BasicConstraints_dealloc(BasicConstraints* self)
17330 {
17331     TraceMethodEnter(self);
17332 
17333     Py_TYPE(self)->tp_free((PyObject*)self);
17334 }
17335 
17336 PyDoc_STRVAR(BasicConstraints_doc,
17337 "An object representing X509 Basic Constraints Extension");
17338 
17339 static int
BasicConstraints_init(BasicConstraints * self,PyObject * args,PyObject * kwds)17340 BasicConstraints_init(BasicConstraints *self, PyObject *args, PyObject *kwds)
17341 {
17342     static char *kwlist[] = {"basic_constraints", NULL};
17343     SecItem *py_sec_item;
17344 
17345     TraceMethodEnter(self);
17346 
17347     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!:BasicConstraints", kwlist,
17348                                      &SecItemType, &py_sec_item))
17349 
17350         return -1;
17351 
17352     if (CERT_DecodeBasicConstraintValue(&self->bc, &py_sec_item->item) != SECSuccess) {
17353         set_nspr_error("cannot decode Basic Constraints");
17354         return -1;
17355     }
17356 
17357     return 0;
17358 }
17359 
17360 static PyObject *
BasicConstraints_str(BasicConstraints * self)17361 BasicConstraints_str(BasicConstraints *self)
17362 {
17363     return PyUnicode_FromFormat("is_ca=%s path_len=%d",
17364                                 self->bc.isCA ? "True" : "False", self->bc.pathLenConstraint);
17365 }
17366 
17367 static PyTypeObject BasicConstraintsType = {
17368     PyVarObject_HEAD_INIT(NULL, 0)
17369     "nss.nss.BasicConstraints",			/* tp_name */
17370     sizeof(BasicConstraints),			/* tp_basicsize */
17371     0,						/* tp_itemsize */
17372     (destructor)BasicConstraints_dealloc,	/* tp_dealloc */
17373     0,						/* tp_print */
17374     0,						/* tp_getattr */
17375     0,						/* tp_setattr */
17376     0,						/* tp_compare */
17377     0,						/* tp_repr */
17378     0,						/* tp_as_number */
17379     0,						/* tp_as_sequence */
17380     0,						/* tp_as_mapping */
17381     0,						/* tp_hash */
17382     0,						/* tp_call */
17383     (reprfunc)BasicConstraints_str,		/* tp_str */
17384     0,						/* tp_getattro */
17385     0,						/* tp_setattro */
17386     0,						/* tp_as_buffer */
17387     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,	/* tp_flags */
17388     BasicConstraints_doc,			/* tp_doc */
17389     (traverseproc)0,				/* tp_traverse */
17390     (inquiry)0,					/* tp_clear */
17391     0,						/* tp_richcompare */
17392     0,						/* tp_weaklistoffset */
17393     0,						/* tp_iter */
17394     0,						/* tp_iternext */
17395     BasicConstraints_methods,			/* tp_methods */
17396     BasicConstraints_members,			/* tp_members */
17397     BasicConstraints_getseters,			/* tp_getset */
17398     0,						/* tp_base */
17399     0,						/* tp_dict */
17400     0,						/* tp_descr_get */
17401     0,						/* tp_descr_set */
17402     0,						/* tp_dictoffset */
17403     (initproc)BasicConstraints_init,		/* tp_init */
17404     0,						/* tp_alloc */
17405     BasicConstraints_new,			/* tp_new */
17406 };
17407 
17408 PyObject *
BasicConstraints_new_from_SECItem(SECItem * item)17409 BasicConstraints_new_from_SECItem(SECItem *item)
17410 {
17411     BasicConstraints *self = NULL;
17412 
17413     TraceObjNewEnter(NULL);
17414 
17415     if ((self = (BasicConstraints *) BasicConstraintsType.tp_new(&BasicConstraintsType, NULL, NULL)) == NULL) {
17416         return NULL;
17417     }
17418 
17419     if (CERT_DecodeBasicConstraintValue(&self->bc, item) != SECSuccess) {
17420         set_nspr_error("cannot decode Basic Constraints");
17421         Py_CLEAR(self);
17422         return NULL;
17423     }
17424 
17425     TraceObjNewLeave(self);
17426     return (PyObject *) self;
17427 }
17428 
17429 /* ========================================================================== */
17430 /* ========================== CertAttribute Class =========================== */
17431 /* ========================================================================== */
17432 
17433 /* ============================ Attribute Access ============================ */
17434 
17435 static PyObject *
CertAttribute_get_type_oid(CertAttribute * self,void * closure)17436 CertAttribute_get_type_oid(CertAttribute *self, void *closure)
17437 {
17438     TraceMethodEnter(self);
17439 
17440     return SecItem_new_from_SECItem(&self->attr.attrType, SECITEM_oid);
17441 }
17442 
17443 static PyObject *
CertAttribute_get_type_tag(CertAttribute * self,void * closure)17444 CertAttribute_get_type_tag(CertAttribute *self, void *closure)
17445 {
17446     TraceMethodEnter(self);
17447 
17448     return oid_secitem_to_pyint_tag(&self->attr.attrType);
17449 }
17450 
17451 static PyObject *
CertAttribute_get_type_str(CertAttribute * self,void * closure)17452 CertAttribute_get_type_str(CertAttribute *self, void *closure)
17453 {
17454     TraceMethodEnter(self);
17455 
17456     return oid_secitem_to_pystr_desc(&self->attr.attrType);
17457 }
17458 
17459 static PyObject *
CertAttribute_get_values(CertAttribute * self,void * closure)17460 CertAttribute_get_values(CertAttribute *self, void *closure)
17461 {
17462     Py_ssize_t i;
17463     PyObject *tuple = NULL;
17464     PyObject *obj = NULL;
17465 
17466     TraceMethodEnter(self);
17467 
17468     if ((tuple = PyTuple_New(self->n_values)) == NULL) {
17469         goto fail;
17470     }
17471 
17472     for (i = 0; i < self->n_values; i++) {
17473         /* NSS WART - extensions are not an array of SECItems like all other attributes */
17474         if (self->oid_tag == SEC_OID_PKCS9_EXTENSION_REQUEST) {
17475             if ((obj = CertificateExtension_new_from_CERTCertExtension(self->extensions[i])) == NULL) {
17476                 goto fail;
17477             }
17478         } else {
17479             if ((obj = SecItem_new_from_SECItem(self->attr.attrValue[i], SECITEM_unknown)) == NULL) {
17480                 goto fail;
17481             }
17482         }
17483         PyTuple_SetItem(tuple, i, obj);
17484     }
17485 
17486     return tuple;
17487  fail:
17488     Py_XDECREF(tuple);
17489     Py_XDECREF(obj);
17490     return NULL;
17491 }
17492 
17493 static
17494 PyGetSetDef CertAttribute_getseters[] = {
17495     {"type_oid", (getter)CertAttribute_get_type_oid, (setter)NULL, "type OID as SecItem", NULL},
17496     {"type_tag", (getter)CertAttribute_get_type_tag, (setter)NULL, "type TAG as a enumerated constant (e.g. tag) ", NULL},
17497     {"type_str", (getter)CertAttribute_get_type_str, (setter)NULL, "type as string description", NULL},
17498     {"values",   (getter)CertAttribute_get_values, (setter)NULL, "tuple of CertificateExtension objects if "
17499                                                                  "type_tag == SEC_OID_PKCS9_EXTENSION_REQUEST "
17500                                                                  "else tuple of SecItem objects", NULL},
17501     {NULL}  /* Sentinel */
17502 };
17503 
17504 static PyMemberDef CertAttribute_members[] = {
17505     {NULL}  /* Sentinel */
17506 };
17507 
17508 /* ============================== Class Methods ============================= */
17509 
17510 static PyObject *
CertAttribute_format_lines(CertAttribute * self,PyObject * args,PyObject * kwds)17511 CertAttribute_format_lines(CertAttribute *self, PyObject *args, PyObject *kwds)
17512 {
17513     static char *kwlist[] = {"level", NULL};
17514     int level = 0;
17515     PyObject *lines = NULL;
17516     PyObject *obj = NULL;
17517     Py_ssize_t i;
17518 
17519     TraceMethodEnter(self);
17520 
17521     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:format_lines", kwlist, &level))
17522         return NULL;
17523 
17524     if ((lines = PyList_New(0)) == NULL) {
17525         return NULL;
17526     }
17527 
17528     if ((obj = oid_secitem_to_pystr_desc(&self->attr.attrType)) == NULL) {
17529         goto fail;
17530     }
17531     FMT_OBJ_AND_APPEND(lines, _("Type"), obj, level, fail);
17532     Py_CLEAR(obj);
17533 
17534     if ((obj = PyUnicode_FromFormat("Values (%zd total)", self->n_values)) == NULL) {
17535         goto fail;
17536     }
17537     FMT_OBJ_AND_APPEND(lines, NULL, obj, level, fail);
17538     Py_CLEAR(obj);
17539 
17540     for (i = 0; i < self->n_values; i++) {
17541         if ((obj = PyUnicode_FromFormat("Value [%zd]", i)) == NULL) {
17542             goto fail;
17543         }
17544         FMT_OBJ_AND_APPEND(lines, NULL, obj, level+1, fail);
17545         Py_CLEAR(obj);
17546 
17547         /* NSS WART - extensions are not an array of SECItems like all other attributes */
17548         if (self->oid_tag == SEC_OID_PKCS9_EXTENSION_REQUEST) {
17549             if ((obj = CertificateExtension_new_from_CERTCertExtension(self->extensions[i])) == NULL) {
17550                 goto fail;
17551             }
17552             CALL_FORMAT_LINES_AND_APPEND(lines, obj, level+2, fail);
17553         } else {
17554             if ((obj = der_any_secitem_to_pystr(self->attr.attrValue[i])) == NULL) {
17555                 goto fail;
17556             }
17557             FMT_OBJ_AND_APPEND(lines, NULL, obj, level+2, fail);
17558         }
17559         Py_CLEAR(obj);
17560     }
17561 
17562     return lines;
17563  fail:
17564     Py_XDECREF(obj);
17565     Py_XDECREF(lines);
17566     return NULL;
17567 }
17568 
17569 static PyObject *
CertAttribute_format(CertAttribute * self,PyObject * args,PyObject * kwds)17570 CertAttribute_format(CertAttribute *self, PyObject *args, PyObject *kwds)
17571 {
17572     TraceMethodEnter(self);
17573 
17574     return format_from_lines((format_lines_func)CertAttribute_format_lines, (PyObject *)self, args, kwds);
17575 }
17576 
17577 static PyObject *
CertAttribute_str(CertAttribute * self)17578 CertAttribute_str(CertAttribute *self)
17579 {
17580     PyObject *py_formatted_result = NULL;
17581 
17582     TraceMethodEnter(self);
17583 
17584     py_formatted_result =  CertAttribute_format(self, empty_tuple, NULL);
17585     return py_formatted_result;
17586 
17587 }
17588 
17589 static PyMethodDef CertAttribute_methods[] = {
17590     {"format_lines", (PyCFunction)CertAttribute_format_lines,   METH_VARARGS|METH_KEYWORDS, generic_format_lines_doc},
17591     {"format",       (PyCFunction)CertAttribute_format,         METH_VARARGS|METH_KEYWORDS, generic_format_doc},
17592     {NULL, NULL}  /* Sentinel */
17593 };
17594 
17595 /* =========================== Sequence Protocol ============================ */
17596 static Py_ssize_t
CertAttribute_length(CertAttribute * self)17597 CertAttribute_length(CertAttribute *self)
17598 {
17599     return self->n_values;
17600 }
17601 
17602 static PyObject *
CertAttribute_item(CertAttribute * self,register Py_ssize_t i)17603 CertAttribute_item(CertAttribute *self, register Py_ssize_t i)
17604 {
17605     if (i < 0 || i >= self->n_values) {
17606         PyErr_SetString(PyExc_IndexError, "CertAttribute index out of range");
17607         return NULL;
17608     }
17609 
17610     /* NSS WART - extensions are not an array of SECItems like all other attributes */
17611     if (self->oid_tag == SEC_OID_PKCS9_EXTENSION_REQUEST) {
17612         return CertificateExtension_new_from_CERTCertExtension(self->extensions[i]);
17613     } else {
17614         return SecItem_new_from_SECItem(self->attr.attrValue[i], SECITEM_unknown);
17615     }
17616 }
17617 
17618 
17619 /* =========================== Class Construction =========================== */
17620 
17621 static PyObject *
CertAttribute_new(PyTypeObject * type,PyObject * args,PyObject * kwds)17622 CertAttribute_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
17623 {
17624     CertAttribute *self;
17625 
17626     TraceObjNewEnter(type);
17627 
17628     if ((self = (CertAttribute *)type->tp_alloc(type, 0)) == NULL) {
17629         return NULL;
17630     }
17631 
17632     if ((self->arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE)) == NULL) {
17633         type->tp_free(self);
17634         return set_nspr_error(NULL);
17635     }
17636 
17637     memset(&self->attr, 0, sizeof(self->attr));
17638     self->oid_tag = SEC_OID_UNKNOWN;
17639     self->n_values = 0;
17640     self->extensions = NULL;
17641 
17642     TraceObjNewLeave(self);
17643     return (PyObject *)self;
17644 }
17645 static void
CertAttribute_dealloc(CertAttribute * self)17646 CertAttribute_dealloc(CertAttribute* self)
17647 {
17648     TraceMethodEnter(self);
17649 
17650     PORT_FreeArena(self->arena, PR_FALSE);
17651     Py_TYPE(self)->tp_free((PyObject*)self);
17652 }
17653 
17654 PyDoc_STRVAR(CertAttribute_doc,
17655 "CertAttribute()\n\
17656 \n\
17657 An object representing CertAttribute.\n\
17658 ");
17659 
17660 static int
CertAttribute_init(CertAttribute * self,PyObject * args,PyObject * kwds)17661 CertAttribute_init(CertAttribute *self, PyObject *args, PyObject *kwds)
17662 {
17663     static char *kwlist[] = {"arg", NULL};
17664     PyObject *arg;
17665 
17666     TraceMethodEnter(self);
17667 
17668     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|i:CertAttribute", kwlist,
17669                                      &arg))
17670         return -1;
17671 
17672     return 0;
17673 }
17674 
17675 static PySequenceMethods CertAttribute_as_sequence = {
17676     (lenfunc)CertAttribute_length,		/* sq_length */
17677     0,						/* sq_concat */
17678     0,						/* sq_repeat */
17679     (ssizeargfunc)CertAttribute_item,		/* sq_item */
17680     0,						/* sq_slice */
17681     0,						/* sq_ass_item */
17682     0,						/* sq_ass_slice */
17683     0,						/* sq_contains */
17684     0,						/* sq_inplace_concat */
17685     0,						/* sq_inplace_repeat */
17686 };
17687 
17688 static PyTypeObject CertAttributeType = {
17689     PyVarObject_HEAD_INIT(NULL, 0)
17690     "nss.nss.CertAttribute",			/* tp_name */
17691     sizeof(CertAttribute),			/* tp_basicsize */
17692     0,						/* tp_itemsize */
17693     (destructor)CertAttribute_dealloc,		/* tp_dealloc */
17694     0,						/* tp_print */
17695     0,						/* tp_getattr */
17696     0,						/* tp_setattr */
17697     0,						/* tp_compare */
17698     0,						/* tp_repr */
17699     0,						/* tp_as_number */
17700     &CertAttribute_as_sequence,			/* tp_as_sequence */
17701     0,						/* tp_as_mapping */
17702     0,						/* tp_hash */
17703     0,						/* tp_call */
17704     (reprfunc)CertAttribute_str,		/* tp_str */
17705     0,						/* tp_getattro */
17706     0,						/* tp_setattro */
17707     0,						/* tp_as_buffer */
17708     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,	/* tp_flags */
17709     CertAttribute_doc,				/* tp_doc */
17710     (traverseproc)0,				/* tp_traverse */
17711     (inquiry)0,					/* tp_clear */
17712     0,						/* tp_richcompare */
17713     0,						/* tp_weaklistoffset */
17714     0,						/* tp_iter */
17715     0,						/* tp_iternext */
17716     CertAttribute_methods,			/* tp_methods */
17717     CertAttribute_members,			/* tp_members */
17718     CertAttribute_getseters,			/* tp_getset */
17719     0,						/* tp_base */
17720     0,						/* tp_dict */
17721     0,						/* tp_descr_get */
17722     0,						/* tp_descr_set */
17723     0,						/* tp_dictoffset */
17724     (initproc)CertAttribute_init,		/* tp_init */
17725     0,						/* tp_alloc */
17726     CertAttribute_new,				/* tp_new */
17727 };
17728 
17729 static PyObject *
CertAttribute_new_from_CERTAttribute(CERTAttribute * attr)17730 CertAttribute_new_from_CERTAttribute(CERTAttribute *attr)
17731 {
17732     Py_ssize_t i;
17733     CertAttribute *self = NULL;
17734 
17735     TraceObjNewEnter(NULL);
17736 
17737     if ((self = (CertAttribute *) CertAttributeType.tp_new(&CertAttributeType, NULL, NULL)) == NULL) {
17738         return NULL;
17739     }
17740 
17741     if (SECITEM_CopyItem(self->arena, &self->attr.attrType, &attr->attrType) != SECSuccess) {
17742         return NULL;
17743     }
17744 
17745     self->oid_tag = SECOID_FindOIDTag(&self->attr.attrType);
17746 
17747     /* NSS WART - extensions are not an array of SECItems like all other attributes */
17748     if (self->oid_tag == SEC_OID_PKCS9_EXTENSION_REQUEST) {
17749         if (CERTCertExtensions_from_CERTAttribute(self->arena, attr, &self->extensions) != SECSuccess) {
17750             return NULL;
17751         }
17752         self->n_values = CERTCertExtension_count(self->extensions);
17753         self->attr.attrValue = NULL;
17754     } else {
17755         Py_ssize_t count;
17756         SECItem **values;
17757 
17758         count = 0;
17759         if (attr->attrValue) {
17760             for (values = attr->attrValue; values[count]; count++);
17761         }
17762         self->n_values = count;
17763 
17764         if ((self->attr.attrValue = PORT_ArenaZNewArray(self->arena, SECItem *, self->n_values+1)) == NULL) {
17765             return NULL;
17766         }
17767 
17768         for (i = 0; i < self->n_values; i++) {
17769             if ((self->attr.attrValue[i] = SECITEM_ArenaDupItem(self->arena, attr->attrValue[i])) == NULL) {
17770                 return NULL;
17771             }
17772         }
17773     }
17774 
17775     TraceObjNewLeave(self);
17776     return (PyObject *) self;
17777 }
17778 
17779 /* ========================================================================== */
17780 /* ======================= CertificateRequest Class ========================= */
17781 /* ========================================================================== */
17782 
17783 static SECStatus
CERTCertExtensions_from_CERTAttribute(PRArenaPool * arena,CERTAttribute * attr,CERTCertExtension *** exts)17784 CERTCertExtensions_from_CERTAttribute(PRArenaPool *arena,
17785                                       CERTAttribute *attr, CERTCertExtension ***exts)
17786 {
17787     if (attr == NULL) {
17788         /* None of the attributes was an extension, return success with empty extension list */
17789         *exts = NULL;
17790         return SECSuccess;
17791     }
17792 
17793     if (attr->attrValue == NULL) {
17794 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
17795         return SECFailure;
17796     }
17797 
17798     return(SEC_ASN1DecodeItem(arena, exts,
17799             SEC_ASN1_GET(CERT_SequenceOfCertExtensionTemplate),
17800             *attr->attrValue));
17801 }
17802 
17803 /* NSS WART, CERT_GetCertificateRequestExtensions is broken, assumes extensions
17804  * will be first cert request attribute, but that's an invalid assumption
17805  *
17806  * We also break the logic into two parts, CERTCertExtensions_from_CERTAttribute()
17807  * which is needed elsewhere.
17808  */
17809 
17810 static SECStatus
My_CERT_GetCertificateRequestExtensions(CERTCertificateRequest * req,CERTCertExtension *** exts)17811 My_CERT_GetCertificateRequestExtensions(CERTCertificateRequest *req, CERTCertExtension ***exts)
17812 {
17813     CERTAttribute **attrs, *attr;
17814 
17815     if (req == NULL || exts == NULL) {
17816 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
17817         return SECFailure;
17818     }
17819 
17820     if (req->attributes == NULL) {
17821         /* No attributes, return success with empty extension list */
17822         *exts = NULL;
17823         return SECSuccess;
17824     }
17825 
17826     /* Search for an extension attribute in set of attributes */
17827     attrs = req->attributes;
17828     for (attr = *attrs; attr; attr = *(++attrs)) {
17829         if (SECOID_FindOIDTag(&attr->attrType) == SEC_OID_PKCS9_EXTENSION_REQUEST) {
17830             break;
17831         }
17832     }
17833 
17834     return CERTCertExtensions_from_CERTAttribute(req->arena, attr, exts);
17835 }
17836 
17837 static int
CertificateRequest_init_from_SECItem(CertificateRequest * self,SECItem * der_cert_req)17838 CertificateRequest_init_from_SECItem(CertificateRequest *self, SECItem *der_cert_req)
17839 {
17840     if ((self->cert_req = PORT_ArenaZAlloc(self->arena, sizeof(CERTCertificateRequest))) == NULL) {
17841         set_nspr_error(NULL);
17842         return -1;
17843     }
17844     self->cert_req->arena = self->arena;
17845 
17846     /* Since cert request is a signed data, must decode to get the inner data */
17847     if (SEC_ASN1DecodeItem(self->arena, &self->signed_data,
17848                            SEC_ASN1_GET(CERT_SignedDataTemplate),
17849                            der_cert_req) != SECSuccess) {
17850         set_nspr_error(NULL);
17851         return -1;
17852     }
17853 
17854     if (SEC_ASN1DecodeItem(self->arena, self->cert_req,
17855                            SEC_ASN1_GET(CERT_CertificateRequestTemplate),
17856                            &self->signed_data.data) != SECSuccess) {
17857         set_nspr_error(NULL);
17858         return -1;
17859     }
17860 
17861     if (CERT_VerifySignedDataWithPublicKeyInfo(&self->signed_data,
17862                                                &self->cert_req->subjectPublicKeyInfo,
17863                                                NULL) != SECSuccess) {
17864         set_nspr_error(NULL);
17865         return -1;
17866     }
17867 
17868     if (My_CERT_GetCertificateRequestExtensions(self->cert_req, &self->extensions) != SECSuccess) {
17869         set_nspr_error("CERT_GetCertificateRequestExtensions failed");
17870         return -1;
17871     }
17872 
17873    return 0;
17874 }
17875 /* ============================ Attribute Access ============================ */
17876 
17877 static PyObject *
CertificateRequest_get_subject(CertificateRequest * self,void * closure)17878 CertificateRequest_get_subject(CertificateRequest *self, void *closure)
17879 {
17880     TraceMethodEnter(self);
17881 
17882     return DN_new_from_CERTName(&self->cert_req->subject);
17883 }
17884 
17885 static PyObject *
CertificateRequest_get_version(CertificateRequest * self,void * closure)17886 CertificateRequest_get_version(CertificateRequest *self, void *closure)
17887 {
17888     TraceMethodEnter(self);
17889 
17890     return integer_secitem_to_pylong(&self->cert_req->version);
17891 }
17892 
17893 static PyObject *
CertificateRequest_get_subject_public_key_info(CertificateRequest * self,void * closure)17894 CertificateRequest_get_subject_public_key_info(CertificateRequest *self, void *closure)
17895 {
17896     TraceMethodEnter(self);
17897 
17898     return SubjectPublicKeyInfo_new_from_CERTSubjectPublicKeyInfo(
17899                &self->cert_req->subjectPublicKeyInfo);
17900 }
17901 
17902 
17903 
17904 static PyObject *
CertificateRequest_get_extensions(CertificateRequest * self,void * closure)17905 CertificateRequest_get_extensions(CertificateRequest *self, void *closure)
17906 {
17907     TraceMethodEnter(self);
17908 
17909     return CERTCertExtension_tuple(self->extensions, AsObject);
17910 }
17911 
17912 static PyObject *
CertificateRequest_get_attributes(CertificateRequest * self,void * closure)17913 CertificateRequest_get_attributes(CertificateRequest *self, void *closure)
17914 {
17915     CERTAttribute **attributes_list = NULL, **attributes = NULL;
17916     Py_ssize_t num_attributes, i;
17917     PyObject *attributes_tuple;
17918 
17919     TraceMethodEnter(self);
17920 
17921     num_attributes = 0;
17922 
17923     attributes_list = self->cert_req->attributes;
17924     if (attributes_list == NULL) {
17925         Py_INCREF(empty_tuple);
17926         return empty_tuple;
17927     }
17928 
17929     /* First count how many attributes the cert request has */
17930     for (attributes = attributes_list, num_attributes = 0;
17931          attributes && *attributes;
17932          attributes++, num_attributes++);
17933 
17934     /* Allocate a tuple */
17935     if ((attributes_tuple = PyTuple_New(num_attributes)) == NULL) {
17936         return NULL;
17937     }
17938 
17939     /* Copy the attributes into the tuple */
17940     for (attributes = attributes_list, i = 0; attributes && *attributes; attributes++, i++) {
17941         CERTAttribute *attribute = *attributes;
17942         PyObject *py_cert_attribute;
17943 
17944         if ((py_cert_attribute = CertAttribute_new_from_CERTAttribute(attribute)) == NULL) {
17945             Py_DECREF(attributes_tuple);
17946             return NULL;
17947         }
17948 
17949         PyTuple_SetItem(attributes_tuple, i, py_cert_attribute);
17950     }
17951 
17952     return attributes_tuple;
17953 }
17954 
17955 static
17956 PyGetSetDef CertificateRequest_getseters[] = {
17957     {"subject", (getter)CertificateRequest_get_subject, (setter)NULL,
17958      "subject as an `DN` object", NULL},
17959     {"version", (getter)CertificateRequest_get_version, (setter)NULL,
17960      "version as integer", NULL},
17961     {"subject_public_key_info", (getter)CertificateRequest_get_subject_public_key_info, NULL,
17962      "certificate public info as SubjectPublicKeyInfo object",  NULL},
17963     {"extensions", (getter)CertificateRequest_get_extensions, NULL,
17964      "certificate extensions as a tuple of CertificateExtension objects",  NULL},
17965     {"attributes", (getter)CertificateRequest_get_attributes, NULL,
17966      "certificate request attributes as a tuple of CertAttribute objects",  NULL},
17967 
17968     {NULL}  /* Sentinel */
17969 };
17970 
17971 static PyMemberDef CertificateRequest_members[] = {
17972     {NULL}  /* Sentinel */
17973 };
17974 
17975 /* ============================== Class Methods ============================= */
17976 
17977 static PyObject *
CertificateRequest_format_lines(CertificateRequest * self,PyObject * args,PyObject * kwds)17978 CertificateRequest_format_lines(CertificateRequest *self, PyObject *args, PyObject *kwds)
17979 {
17980     static char *kwlist[] = {"level", NULL};
17981     int level = 0;
17982     Py_ssize_t len, i;
17983     PyObject *lines = NULL;
17984     PyObject *obj = NULL;
17985     PyObject *obj1 = NULL;
17986     PyObject *obj2 = NULL;
17987     PyObject *attributes = NULL;
17988 
17989     TraceMethodEnter(self);
17990 
17991     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:format_lines", kwlist, &level))
17992         return NULL;
17993 
17994     if ((lines = PyList_New(0)) == NULL) {
17995         goto fail;
17996     }
17997 
17998     FMT_LABEL_AND_APPEND(lines, _("Data"), level+1, fail);
17999 
18000     if ((obj = CertificateRequest_get_version(self, NULL)) == NULL) {
18001         goto fail;
18002     }
18003     if ((obj2 = obj_sprintf("%d (%#x)", obj, obj)) == NULL) {
18004         goto fail;
18005     }
18006     FMT_OBJ_AND_APPEND(lines, _("Version"), obj2, level+2, fail);
18007     Py_CLEAR(obj);
18008     Py_CLEAR(obj1);
18009     Py_CLEAR(obj2);
18010 
18011     if ((obj = CertificateRequest_get_subject(self, NULL)) == NULL) {
18012         goto fail;
18013     }
18014     FMT_OBJ_AND_APPEND(lines, _("Subject"), obj, level+2, fail);
18015     Py_CLEAR(obj);
18016 
18017     FMT_LABEL_AND_APPEND(lines, _("Subject Public Key Info"), level+2, fail);
18018 
18019     if ((obj = CertificateRequest_get_subject_public_key_info(self, NULL)) == NULL) {
18020         goto fail;
18021     }
18022 
18023     CALL_FORMAT_LINES_AND_APPEND(lines, obj, level+3, fail);
18024     Py_CLEAR(obj);
18025 
18026     if ((attributes = CertificateRequest_get_attributes(self, NULL)) == NULL) {
18027         goto fail;
18028     }
18029 
18030     len = PyTuple_Size(attributes);
18031     if ((obj = PyUnicode_FromFormat("Attributes: (%zd total)", len)) == NULL) {
18032         goto fail;
18033     }
18034     FMT_OBJ_AND_APPEND(lines, NULL, obj, level+1, fail);
18035     Py_CLEAR(obj);
18036 
18037     for (i = 0; i < len; i++) {
18038         if ((obj = PyUnicode_FromFormat("Attribute [%zd]", i)) == NULL) {
18039             goto fail;
18040         }
18041         FMT_OBJ_AND_APPEND(lines, NULL, obj, level+2, fail);
18042         Py_CLEAR(obj);
18043 
18044         obj = PyTuple_GetItem(attributes, i);
18045         CALL_FORMAT_LINES_AND_APPEND(lines, obj, level+3, fail);
18046         FMT_LABEL_AND_APPEND(lines, NULL, 0, fail);
18047     }
18048     Py_CLEAR(attributes);
18049 
18050     return lines;
18051 
18052  fail:
18053     Py_XDECREF(obj);
18054     Py_XDECREF(obj1);
18055     Py_XDECREF(obj2);
18056     Py_XDECREF(lines);
18057     Py_XDECREF(attributes);
18058     return NULL;
18059 }
18060 
18061 static PyObject *
CertificateRequest_format(CertificateRequest * self,PyObject * args,PyObject * kwds)18062 CertificateRequest_format(CertificateRequest *self, PyObject *args, PyObject *kwds)
18063 {
18064     TraceMethodEnter(self);
18065 
18066     return format_from_lines((format_lines_func)CertificateRequest_format_lines, (PyObject *)self, args, kwds);
18067 }
18068 
18069 static PyObject *
CertificateRequest_str(CertificateRequest * self)18070 CertificateRequest_str(CertificateRequest *self)
18071 {
18072     PyObject *py_formatted_result = NULL;
18073 
18074     py_formatted_result = CertificateRequest_format(self, empty_tuple, NULL);
18075     return py_formatted_result;
18076 
18077 }
18078 
18079 
18080 static PyMethodDef CertificateRequest_methods[] = {
18081     {"format_lines",           (PyCFunction)CertificateRequest_format_lines,           METH_VARARGS|METH_KEYWORDS, generic_format_lines_doc},
18082     {"format",                 (PyCFunction)CertificateRequest_format,                 METH_VARARGS|METH_KEYWORDS, generic_format_doc},
18083     {NULL, NULL}  /* Sentinel */
18084 };
18085 
18086 /* =========================== Class Construction =========================== */
18087 
18088 static PyObject *
CertificateRequest_new(PyTypeObject * type,PyObject * args,PyObject * kwds)18089 CertificateRequest_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
18090 {
18091     CertificateRequest *self;
18092 
18093     TraceObjNewEnter(type);
18094 
18095     if ((self = (CertificateRequest *)type->tp_alloc(type, 0)) == NULL) {
18096         return NULL;
18097     }
18098 
18099     if ((self->arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE)) == NULL) {
18100         type->tp_free(self);
18101         return set_nspr_error(NULL);
18102     }
18103 
18104     self->cert_req = NULL;
18105     memset(&self->signed_data, 0, sizeof(self->signed_data));
18106     self->extensions = NULL;
18107 
18108     TraceObjNewLeave(self);
18109     return (PyObject *)self;
18110 }
18111 
18112 static void
CertificateRequest_dealloc(CertificateRequest * self)18113 CertificateRequest_dealloc(CertificateRequest* self)
18114 {
18115     TraceMethodEnter(self);
18116 
18117     /*
18118      * We could call CERT_DestroyCertificateRequest() but all
18119      * CERT_DestroyCertificateRequest() does is call PORT_FreeArena() on
18120      * the arena stored in the CERTCertificateRequest. All the other
18121      * dealloc routines for objects with arenas call PORT_FreeArena()
18122      * explicitly, so for consistency and to make sure the freeing of
18123      * the arena is explicit rather than hidden we do the same here.
18124      *
18125      * Also, self->signed_data does not need to be explicitly freed
18126      * because it's allocated out of the arena.
18127      */
18128 
18129     if (self->arena) {
18130         PORT_FreeArena(self->arena, PR_FALSE);
18131     }
18132     Py_TYPE(self)->tp_free((PyObject*)self);
18133 }
18134 
18135 PyDoc_STRVAR(CertificateRequest_doc,
18136 "CertificateRequest(data=None)\n\
18137 \n\
18138 :Parameters:\n\
18139     data : SecItem or str or any buffer compatible object\n\
18140         Data to initialize the certificate request from, must be in DER format\n\
18141 \n\
18142 An object representing a certificate request");
18143 
18144 static int
CertificateRequest_init(CertificateRequest * self,PyObject * args,PyObject * kwds)18145 CertificateRequest_init(CertificateRequest *self, PyObject *args, PyObject *kwds)
18146 {
18147     static char *kwlist[] = {"data", NULL};
18148     SECItem_param *der_item = NULL;
18149     int result = 0;
18150 
18151     TraceMethodEnter(self);
18152 
18153     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O&:CertificateRequest", kwlist,
18154                                      SECItemOrNoneConvert, &der_item))
18155         return -1;
18156 
18157     if (der_item) {
18158         result= CertificateRequest_init_from_SECItem(self, &der_item->item);
18159     }
18160     SECItem_param_release(der_item);
18161     return result;
18162 }
18163 
18164 static PyTypeObject CertificateRequestType = {
18165     PyVarObject_HEAD_INIT(NULL, 0)
18166     "nss.nss.CertificateRequest",		/* tp_name */
18167     sizeof(CertificateRequest),			/* tp_basicsize */
18168     0,						/* tp_itemsize */
18169     (destructor)CertificateRequest_dealloc,	/* tp_dealloc */
18170     0,						/* tp_print */
18171     0,						/* tp_getattr */
18172     0,						/* tp_setattr */
18173     0,						/* tp_compare */
18174     0,						/* tp_repr */
18175     0,						/* tp_as_number */
18176     0,						/* tp_as_sequence */
18177     0,						/* tp_as_mapping */
18178     0,						/* tp_hash */
18179     0,						/* tp_call */
18180     (reprfunc)CertificateRequest_str,		/* tp_str */
18181     0,						/* tp_getattro */
18182     0,						/* tp_setattro */
18183     0,						/* tp_as_buffer */
18184     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,	/* tp_flags */
18185     CertificateRequest_doc,			/* tp_doc */
18186     (traverseproc)0,				/* tp_traverse */
18187     (inquiry)0,					/* tp_clear */
18188     0,						/* tp_richcompare */
18189     0,						/* tp_weaklistoffset */
18190     0,						/* tp_iter */
18191     0,						/* tp_iternext */
18192     CertificateRequest_methods,			/* tp_methods */
18193     CertificateRequest_members,			/* tp_members */
18194     CertificateRequest_getseters,		/* tp_getset */
18195     0,						/* tp_base */
18196     0,						/* tp_dict */
18197     0,						/* tp_descr_get */
18198     0,						/* tp_descr_set */
18199     0,						/* tp_dictoffset */
18200     (initproc)CertificateRequest_init,		/* tp_init */
18201     0,						/* tp_alloc */
18202     CertificateRequest_new,			/* tp_new */
18203 };
18204 
18205 /* ========================================================================== */
18206 /* ========================== InitParameters Class ========================== */
18207 /* ========================================================================== */
18208 
18209 /* ============================ Attribute Access ============================ */
18210 
18211 static PyObject *
InitParameters_get_password_required(InitParameters * self,void * closure)18212 InitParameters_get_password_required(InitParameters *self, void *closure)
18213 {
18214     TraceMethodEnter(self);
18215 
18216     return PyBool_FromLong(self->params.passwordRequired);
18217 }
18218 
18219 static int
InitParameters_set_password_required(InitParameters * self,PyObject * value,void * closure)18220 InitParameters_set_password_required(InitParameters *self, PyObject *value, void *closure)
18221 {
18222     TraceMethodEnter(self);
18223 
18224     if (value == NULL) {
18225         PyErr_SetString(PyExc_TypeError, "Cannot delete the password_required attribute");
18226         return -1;
18227     }
18228 
18229     switch(PyObject_IsTrue(value)) {
18230     case 0:
18231         self->params.passwordRequired = PR_FALSE;
18232         return 0;
18233     case 1:
18234         self->params.passwordRequired = PR_TRUE;
18235         return 0;
18236     default:
18237         PyErr_SetString(PyExc_TypeError, "The password_required attribute value must be a boolean");
18238         return -1;
18239     }
18240 }
18241 
18242 static PyObject *
InitParameters_get_min_password_len(InitParameters * self,void * closure)18243 InitParameters_get_min_password_len(InitParameters *self, void *closure)
18244 {
18245     TraceMethodEnter(self);
18246 
18247     return PyLong_FromLong(self->params.minPWLen);
18248 }
18249 
18250 static int
InitParameters_set_min_password_len(InitParameters * self,PyObject * value,void * closure)18251 InitParameters_set_min_password_len(InitParameters *self, PyObject *value, void *closure)
18252 {
18253     TraceMethodEnter(self);
18254 
18255     if (value == NULL) {
18256         PyErr_SetString(PyExc_TypeError, "Cannot delete the min_password_len attribute");
18257         return -1;
18258     }
18259 
18260     if (!PyInteger_Check(value)) {
18261         PyErr_SetString(PyExc_TypeError, "The min_password_len attribute value must be an integer");
18262         return -1;
18263     }
18264 
18265     self->params.minPWLen = PyLong_AsLong(value);
18266 
18267     return 0;
18268 }
18269 
18270 static PyObject *
InitParameters_get_manufacturer_id(InitParameters * self,void * closure)18271 InitParameters_get_manufacturer_id(InitParameters *self, void *closure)
18272 {
18273     TraceMethodEnter(self);
18274 
18275     if (self->params.manufactureID == NULL) {
18276         Py_RETURN_NONE;
18277     }
18278 
18279     return PyUnicode_DecodeUTF8(self->params.manufactureID, strlen(self->params.manufactureID), NULL);
18280 }
18281 
18282 static int
InitParameters_set_manufacturer_id(InitParameters * self,PyObject * value,void * closure)18283 InitParameters_set_manufacturer_id(InitParameters *self, PyObject *value, void *closure)
18284 {
18285     PyObject *args = NULL;
18286     char *new_value = NULL;
18287 
18288     TraceMethodEnter(self);
18289 
18290     if (value == NULL) {
18291         if (self->params.manufactureID) {
18292             PyMem_Free(self->params.manufactureID);
18293         }
18294         self->params.manufactureID = NULL;
18295         return 0;
18296     }
18297 
18298     if ((args = Py_BuildValue("(O)", value)) == NULL) {
18299         return -1;
18300     }
18301 
18302     if (PyArg_ParseTuple(args, "es", "utf-8", &new_value) == -1) {
18303         Py_DECREF(args);
18304         PyErr_SetString(PyExc_TypeError, "The manufacturer_id attribute value must be a string or unicode");
18305         return -1;
18306     }
18307 
18308     if (self->params.manufactureID) {
18309         PyMem_Free(self->params.manufactureID);
18310         self->params.manufactureID = NULL;
18311     }
18312 
18313     self->params.manufactureID = new_value;
18314     Py_DECREF(args);
18315     return 0;
18316 }
18317 
18318 static PyObject *
InitParameters_get_library_description(InitParameters * self,void * closure)18319 InitParameters_get_library_description(InitParameters *self, void *closure)
18320 {
18321     TraceMethodEnter(self);
18322 
18323     if (self->params.libraryDescription == NULL) {
18324         Py_RETURN_NONE;
18325     }
18326 
18327     return PyUnicode_DecodeUTF8(self->params.libraryDescription, strlen(self->params.libraryDescription), NULL);
18328 }
18329 
18330 static int
InitParameters_set_library_description(InitParameters * self,PyObject * value,void * closure)18331 InitParameters_set_library_description(InitParameters *self, PyObject *value, void *closure)
18332 {
18333     PyObject *args = NULL;
18334     char *new_value = NULL;
18335 
18336     TraceMethodEnter(self);
18337 
18338     if (value == NULL) {
18339         if (self->params.libraryDescription) {
18340             PyMem_Free(self->params.libraryDescription);
18341         }
18342         self->params.libraryDescription = NULL;
18343         return 0;
18344     }
18345 
18346     if ((args = Py_BuildValue("(O)", value)) == NULL) {
18347         return -1;
18348     }
18349 
18350     if (PyArg_ParseTuple(args, "es", "utf-8", &new_value) == -1) {
18351         Py_DECREF(args);
18352         PyErr_SetString(PyExc_TypeError, "The library_description attribute value must be a string or unicode");
18353         return -1;
18354     }
18355 
18356     if (self->params.libraryDescription) {
18357         PyMem_Free(self->params.libraryDescription);
18358         self->params.libraryDescription = NULL;
18359     }
18360 
18361     self->params.libraryDescription = new_value;
18362     Py_DECREF(args);
18363     return 0;
18364 }
18365 
18366 
18367 
18368 static PyObject *
InitParameters_get_crypto_token_description(InitParameters * self,void * closure)18369 InitParameters_get_crypto_token_description(InitParameters *self, void *closure)
18370 {
18371     TraceMethodEnter(self);
18372 
18373     if (self->params.cryptoTokenDescription == NULL) {
18374         Py_RETURN_NONE;
18375     }
18376 
18377     return PyUnicode_DecodeUTF8(self->params.cryptoTokenDescription, strlen(self->params.cryptoTokenDescription), NULL);
18378 }
18379 
18380 static int
InitParameters_set_crypto_token_description(InitParameters * self,PyObject * value,void * closure)18381 InitParameters_set_crypto_token_description(InitParameters *self, PyObject *value, void *closure)
18382 {
18383     PyObject *args = NULL;
18384     char *new_value = NULL;
18385 
18386     TraceMethodEnter(self);
18387 
18388     if (value == NULL) {
18389         if (self->params.cryptoTokenDescription) {
18390             PyMem_Free(self->params.cryptoTokenDescription);
18391         }
18392         self->params.cryptoTokenDescription = NULL;
18393         return 0;
18394     }
18395 
18396     if ((args = Py_BuildValue("(O)", value)) == NULL) {
18397         return -1;
18398     }
18399 
18400     if (PyArg_ParseTuple(args, "es", "utf-8", &new_value) == -1) {
18401         Py_DECREF(args);
18402         PyErr_SetString(PyExc_TypeError, "The crypto_token_description attribute value must be a string or unicode");
18403         return -1;
18404     }
18405 
18406     if (self->params.cryptoTokenDescription) {
18407         PyMem_Free(self->params.cryptoTokenDescription);
18408         self->params.cryptoTokenDescription = NULL;
18409     }
18410 
18411     self->params.cryptoTokenDescription = new_value;
18412     Py_DECREF(args);
18413     return 0;
18414 }
18415 
18416 
18417 
18418 static PyObject *
InitParameters_get_db_token_description(InitParameters * self,void * closure)18419 InitParameters_get_db_token_description(InitParameters *self, void *closure)
18420 {
18421     TraceMethodEnter(self);
18422 
18423     if (self->params.dbTokenDescription == NULL) {
18424         Py_RETURN_NONE;
18425     }
18426 
18427     return PyUnicode_DecodeUTF8(self->params.dbTokenDescription, strlen(self->params.dbTokenDescription), NULL);
18428 }
18429 
18430 static int
InitParameters_set_db_token_description(InitParameters * self,PyObject * value,void * closure)18431 InitParameters_set_db_token_description(InitParameters *self, PyObject *value, void *closure)
18432 {
18433     PyObject *args = NULL;
18434     char *new_value = NULL;
18435 
18436     TraceMethodEnter(self);
18437 
18438     if (value == NULL) {
18439         if (self->params.dbTokenDescription) {
18440             PyMem_Free(self->params.dbTokenDescription);
18441         }
18442         self->params.dbTokenDescription = NULL;
18443         return 0;
18444     }
18445 
18446     if ((args = Py_BuildValue("(O)", value)) == NULL) {
18447         return -1;
18448     }
18449 
18450     if (PyArg_ParseTuple(args, "es", "utf-8", &new_value) == -1) {
18451         Py_DECREF(args);
18452         PyErr_SetString(PyExc_TypeError, "The db_token_description attribute value must be a string or unicode");
18453         return -1;
18454     }
18455 
18456     if (self->params.dbTokenDescription) {
18457         PyMem_Free(self->params.dbTokenDescription);
18458         self->params.dbTokenDescription = NULL;
18459     }
18460 
18461     self->params.dbTokenDescription = new_value;
18462     Py_DECREF(args);
18463     return 0;
18464 }
18465 
18466 static PyObject *
InitParameters_get_fips_token_description(InitParameters * self,void * closure)18467 InitParameters_get_fips_token_description(InitParameters *self, void *closure)
18468 {
18469     TraceMethodEnter(self);
18470 
18471     if (self->params.FIPSTokenDescription == NULL) {
18472         Py_RETURN_NONE;
18473     }
18474 
18475     return PyUnicode_DecodeUTF8(self->params.FIPSTokenDescription, strlen(self->params.FIPSTokenDescription), NULL);
18476 }
18477 
18478 static int
InitParameters_set_fips_token_description(InitParameters * self,PyObject * value,void * closure)18479 InitParameters_set_fips_token_description(InitParameters *self, PyObject *value, void *closure)
18480 {
18481     PyObject *args = NULL;
18482     char *new_value = NULL;
18483 
18484     TraceMethodEnter(self);
18485 
18486     if (value == NULL) {
18487         if (self->params.FIPSTokenDescription) {
18488             PyMem_Free(self->params.FIPSTokenDescription);
18489         }
18490         self->params.FIPSTokenDescription = NULL;
18491         return 0;
18492     }
18493 
18494     if ((args = Py_BuildValue("(O)", value)) == NULL) {
18495         return -1;
18496     }
18497 
18498     if (PyArg_ParseTuple(args, "es", "utf-8", &new_value) == -1) {
18499         Py_DECREF(args);
18500         PyErr_SetString(PyExc_TypeError, "The fips_token_description attribute value must be a string or unicode");
18501         return -1;
18502     }
18503 
18504     if (self->params.FIPSTokenDescription) {
18505         PyMem_Free(self->params.FIPSTokenDescription);
18506         self->params.FIPSTokenDescription = NULL;
18507     }
18508 
18509     self->params.FIPSTokenDescription = new_value;
18510     Py_DECREF(args);
18511     return 0;
18512 }
18513 
18514 static PyObject *
InitParameters_get_crypto_slot_description(InitParameters * self,void * closure)18515 InitParameters_get_crypto_slot_description(InitParameters *self, void *closure)
18516 {
18517     TraceMethodEnter(self);
18518 
18519     if (self->params.cryptoSlotDescription == NULL) {
18520         Py_RETURN_NONE;
18521     }
18522 
18523     return PyUnicode_DecodeUTF8(self->params.cryptoSlotDescription, strlen(self->params.cryptoSlotDescription), NULL);
18524 }
18525 
18526 static int
InitParameters_set_crypto_slot_description(InitParameters * self,PyObject * value,void * closure)18527 InitParameters_set_crypto_slot_description(InitParameters *self, PyObject *value, void *closure)
18528 {
18529     PyObject *args = NULL;
18530     char *new_value = NULL;
18531 
18532     TraceMethodEnter(self);
18533 
18534     if (value == NULL) {
18535         if (self->params.cryptoSlotDescription) {
18536             PyMem_Free(self->params.cryptoSlotDescription);
18537         }
18538         self->params.cryptoSlotDescription = NULL;
18539         return 0;
18540     }
18541 
18542     if ((args = Py_BuildValue("(O)", value)) == NULL) {
18543         return -1;
18544     }
18545 
18546     if (PyArg_ParseTuple(args, "es", "utf-8", &new_value) == -1) {
18547         Py_DECREF(args);
18548         PyErr_SetString(PyExc_TypeError, "The crypto_slot_description attribute value must be a string or unicode");
18549         return -1;
18550     }
18551 
18552     if (self->params.cryptoSlotDescription) {
18553         PyMem_Free(self->params.cryptoSlotDescription);
18554         self->params.cryptoSlotDescription = NULL;
18555     }
18556 
18557     self->params.cryptoSlotDescription = new_value;
18558     Py_DECREF(args);
18559     return 0;
18560 }
18561 
18562 static PyObject *
InitParameters_get_db_slot_description(InitParameters * self,void * closure)18563 InitParameters_get_db_slot_description(InitParameters *self, void *closure)
18564 {
18565     TraceMethodEnter(self);
18566 
18567     if (self->params.dbSlotDescription == NULL) {
18568         Py_RETURN_NONE;
18569     }
18570 
18571     return PyUnicode_DecodeUTF8(self->params.dbSlotDescription, strlen(self->params.dbSlotDescription), NULL);
18572 }
18573 
18574 static int
InitParameters_set_db_slot_description(InitParameters * self,PyObject * value,void * closure)18575 InitParameters_set_db_slot_description(InitParameters *self, PyObject *value, void *closure)
18576 {
18577     PyObject *args = NULL;
18578     char *new_value = NULL;
18579 
18580     TraceMethodEnter(self);
18581 
18582     if (value == NULL) {
18583         if (self->params.dbSlotDescription) {
18584             PyMem_Free(self->params.dbSlotDescription);
18585         }
18586         self->params.dbSlotDescription = NULL;
18587         return 0;
18588     }
18589 
18590     if ((args = Py_BuildValue("(O)", value)) == NULL) {
18591         return -1;
18592     }
18593 
18594     if (PyArg_ParseTuple(args, "es", "utf-8", &new_value) == -1) {
18595         Py_DECREF(args);
18596         PyErr_SetString(PyExc_TypeError, "The db_slot_description attribute value must be a string or unicode");
18597         return -1;
18598     }
18599 
18600     if (self->params.dbSlotDescription) {
18601         PyMem_Free(self->params.dbSlotDescription);
18602         self->params.dbSlotDescription = NULL;
18603     }
18604 
18605     self->params.dbSlotDescription = new_value;
18606     Py_DECREF(args);
18607     return 0;
18608 }
18609 
18610 static PyObject *
InitParameters_get_fips_slot_description(InitParameters * self,void * closure)18611 InitParameters_get_fips_slot_description(InitParameters *self, void *closure)
18612 {
18613     TraceMethodEnter(self);
18614 
18615     if (self->params.FIPSSlotDescription == NULL) {
18616         Py_RETURN_NONE;
18617     }
18618 
18619     return PyUnicode_DecodeUTF8(self->params.FIPSSlotDescription, strlen(self->params.FIPSSlotDescription), NULL);
18620 }
18621 
18622 static int
InitParameters_set_fips_slot_description(InitParameters * self,PyObject * value,void * closure)18623 InitParameters_set_fips_slot_description(InitParameters *self, PyObject *value, void *closure)
18624 {
18625     PyObject *args = NULL;
18626     char *new_value = NULL;
18627 
18628     TraceMethodEnter(self);
18629 
18630     if (value == NULL) {
18631         if (self->params.FIPSSlotDescription) {
18632             PyMem_Free(self->params.FIPSSlotDescription);
18633         }
18634         self->params.FIPSSlotDescription = NULL;
18635         return 0;
18636     }
18637 
18638     if ((args = Py_BuildValue("(O)", value)) == NULL) {
18639         return -1;
18640     }
18641 
18642     if (PyArg_ParseTuple(args, "es", "utf-8", &new_value) == -1) {
18643         Py_DECREF(args);
18644         PyErr_SetString(PyExc_TypeError, "The fips_slot_description attribute value must be a string or unicode");
18645         return -1;
18646     }
18647 
18648     if (self->params.FIPSSlotDescription) {
18649         PyMem_Free(self->params.FIPSSlotDescription);
18650         self->params.FIPSSlotDescription = NULL;
18651     }
18652 
18653     self->params.FIPSSlotDescription = new_value;
18654     Py_DECREF(args);
18655     return 0;
18656 }
18657 
18658 static
18659 PyGetSetDef InitParameters_getseters[] = {
18660     {"password_required",
18661      (getter)InitParameters_get_password_required,
18662      (setter)InitParameters_set_password_required,
18663      "boolean indicating if a password is required", NULL},
18664 
18665     {"min_password_len",
18666      (getter)InitParameters_get_min_password_len,
18667      (setter)InitParameters_set_min_password_len,
18668      "minimum password length", NULL},
18669 
18670     {"manufacturer_id",
18671      (getter)InitParameters_get_manufacturer_id,
18672      (setter)InitParameters_set_manufacturer_id,
18673      "manufacturer id (max 32 chars)", NULL},
18674 
18675     {"library_description",
18676      (getter)InitParameters_get_library_description,
18677      (setter)InitParameters_set_library_description,
18678      "", NULL},
18679 
18680     {"crypto_token_description",
18681      (getter)InitParameters_get_crypto_token_description,
18682      (setter)InitParameters_set_crypto_token_description,
18683      "", NULL},
18684 
18685     {"db_token_description",
18686      (getter)InitParameters_get_db_token_description,
18687      (setter)InitParameters_set_db_token_description,
18688      "", NULL},
18689 
18690     {"fips_token_description",
18691      (getter)InitParameters_get_fips_token_description,
18692      (setter)InitParameters_set_fips_token_description,
18693      "", NULL},
18694 
18695     {"crypto_slot_description",
18696      (getter)InitParameters_get_crypto_slot_description,
18697      (setter)InitParameters_set_crypto_slot_description,
18698      "", NULL},
18699 
18700     {"db_slot_description",
18701      (getter)InitParameters_get_db_slot_description,
18702      (setter)InitParameters_set_db_slot_description,
18703      "", NULL},
18704 
18705     {"fips_slot_description",
18706      (getter)InitParameters_get_fips_slot_description,
18707      (setter)InitParameters_set_fips_slot_description,
18708      "", NULL},
18709 
18710     {NULL}  /* Sentinel */
18711 };
18712 
18713 static PyObject *
InitParameters_format_lines(InitParameters * self,PyObject * args,PyObject * kwds)18714 InitParameters_format_lines(InitParameters *self, PyObject *args, PyObject *kwds)
18715 {
18716     static char *kwlist[] = {"level", NULL};
18717     int level = 0;
18718     PyObject *lines = NULL;
18719     PyObject *obj = NULL;
18720 
18721     TraceMethodEnter(self);
18722 
18723     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:format_lines", kwlist, &level))
18724         return NULL;
18725 
18726     if ((lines = PyList_New(0)) == NULL) {
18727         return NULL;
18728     }
18729 
18730     if ((obj = InitParameters_get_password_required(self, NULL)) == NULL) {
18731         goto fail;
18732     }
18733     FMT_OBJ_AND_APPEND(lines, _("Password Required"), obj, level, fail);
18734     Py_CLEAR(obj);
18735 
18736     if ((obj = InitParameters_get_min_password_len(self, NULL)) == NULL) {
18737         goto fail;
18738     }
18739     FMT_OBJ_AND_APPEND(lines, _("Minimum Password Length"), obj, level, fail);
18740     Py_CLEAR(obj);
18741 
18742     if ((obj = InitParameters_get_manufacturer_id(self, NULL)) == NULL) {
18743         goto fail;
18744     }
18745     FMT_OBJ_AND_APPEND(lines, _("Manufacturer ID"), obj, level, fail);
18746     Py_CLEAR(obj);
18747 
18748     if ((obj = InitParameters_get_library_description(self, NULL)) == NULL) {
18749         goto fail;
18750     }
18751     FMT_OBJ_AND_APPEND(lines, _("Library Description"), obj, level, fail);
18752     Py_CLEAR(obj);
18753 
18754     if ((obj = InitParameters_get_crypto_token_description(self, NULL)) == NULL) {
18755         goto fail;
18756     }
18757     FMT_OBJ_AND_APPEND(lines, _("Crypto Token Description"), obj, level, fail);
18758     Py_CLEAR(obj);
18759 
18760     if ((obj = InitParameters_get_db_token_description(self, NULL)) == NULL) {
18761         goto fail;
18762     }
18763     FMT_OBJ_AND_APPEND(lines, _("Database Token Description"), obj, level, fail);
18764     Py_CLEAR(obj);
18765 
18766     if ((obj = InitParameters_get_fips_token_description(self, NULL)) == NULL) {
18767         goto fail;
18768     }
18769     FMT_OBJ_AND_APPEND(lines, _("FIPS Token Description"), obj, level, fail);
18770     Py_CLEAR(obj);
18771 
18772     if ((obj = InitParameters_get_crypto_slot_description(self, NULL)) == NULL) {
18773         goto fail;
18774     }
18775     FMT_OBJ_AND_APPEND(lines, _("Crypto Slot Description"), obj, level, fail);
18776     Py_CLEAR(obj);
18777 
18778     if ((obj = InitParameters_get_db_slot_description(self, NULL)) == NULL) {
18779         goto fail;
18780     }
18781     FMT_OBJ_AND_APPEND(lines, _("Database Slot Description"), obj, level, fail);
18782     Py_CLEAR(obj);
18783 
18784     if ((obj = InitParameters_get_fips_slot_description(self, NULL)) == NULL) {
18785         goto fail;
18786     }
18787     FMT_OBJ_AND_APPEND(lines, _("FIPS Slot Description"), obj, level, fail);
18788     Py_CLEAR(obj);
18789 
18790     return lines;
18791 
18792  fail:
18793     Py_XDECREF(obj);
18794     Py_XDECREF(lines);
18795     return NULL;
18796 }
18797 
18798 static PyObject *
InitParameters_format(InitParameters * self,PyObject * args,PyObject * kwds)18799 InitParameters_format(InitParameters *self, PyObject *args, PyObject *kwds)
18800 {
18801     TraceMethodEnter(self);
18802 
18803     return format_from_lines((format_lines_func)InitParameters_format_lines, (PyObject *)self, args, kwds);
18804 }
18805 
18806 static PyMemberDef InitParameters_members[] = {
18807     {NULL}  /* Sentinel */
18808 };
18809 
18810 /* ============================== Class Methods ============================= */
18811 
18812 
18813 static PyMethodDef InitParameters_methods[] = {
18814     {"format_lines", (PyCFunction)InitParameters_format_lines,   METH_VARARGS|METH_KEYWORDS, generic_format_lines_doc},
18815     {"format",       (PyCFunction)InitParameters_format,         METH_VARARGS|METH_KEYWORDS, generic_format_doc},
18816     {NULL, NULL}  /* Sentinel */
18817 };
18818 
18819 /* =========================== Class Construction =========================== */
18820 
18821 static PyObject *
InitParameters_new(PyTypeObject * type,PyObject * args,PyObject * kwds)18822 InitParameters_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
18823 {
18824     InitParameters *self;
18825 
18826     TraceObjNewEnter(type);
18827 
18828     if ((self = (InitParameters *)type->tp_alloc(type, 0)) == NULL) {
18829         return NULL;
18830     }
18831 
18832     memset(&self->params, 0, sizeof(self->params));
18833     self->params.length = sizeof(self->params);
18834 
18835     TraceObjNewLeave(self);
18836     return (PyObject *)self;
18837 }
18838 
18839 static void
InitParameters_dealloc(InitParameters * self)18840 InitParameters_dealloc(InitParameters* self)
18841 {
18842     TraceMethodEnter(self);
18843 
18844     if (self->params.manufactureID) {
18845         PyMem_Free(self->params.manufactureID);
18846     }
18847     if (self->params.libraryDescription) {
18848         PyMem_Free(self->params.libraryDescription);
18849     }
18850     if (self->params.cryptoTokenDescription) {
18851         PyMem_Free(self->params.cryptoTokenDescription);
18852     }
18853     if (self->params.dbTokenDescription) {
18854         PyMem_Free(self->params.dbTokenDescription);
18855     }
18856     if (self->params.FIPSTokenDescription) {
18857         PyMem_Free(self->params.FIPSTokenDescription);
18858     }
18859     if (self->params.cryptoSlotDescription) {
18860         PyMem_Free(self->params.cryptoSlotDescription);
18861     }
18862     if (self->params.dbSlotDescription) {
18863         PyMem_Free(self->params.dbSlotDescription);
18864     }
18865     if (self->params.FIPSSlotDescription) {
18866         PyMem_Free(self->params.FIPSSlotDescription);
18867     }
18868 
18869     Py_TYPE(self)->tp_free((PyObject*)self);
18870 }
18871 
18872 PyDoc_STRVAR(InitParameters_doc,
18873 "An object representing NSS Initialization Parameters");
18874 
18875 static int
InitParameters_init(InitParameters * self,PyObject * args,PyObject * kwds)18876 InitParameters_init(InitParameters *self, PyObject *args, PyObject *kwds)
18877 {
18878     static char *kwlist[] = {"password_required",
18879                              "min_password_len",
18880                              "manufacturer_id",
18881                              "library_description",
18882                              "crypto_token_description",
18883                              "db_token_description",
18884                              "fips_token_description",
18885                              "crypto_slot_description",
18886                              "db_slot_description",
18887                              "fips_slot_description",
18888                              NULL};
18889 
18890     PyObject *py_password_required = NULL;
18891     PyObject *py_min_password_len = NULL;
18892     PyObject *py_manufacturer_id = NULL;
18893     PyObject *py_library_description = NULL;
18894     PyObject *py_crypto_token_description = NULL;
18895     PyObject *py_db_token_description = NULL;
18896     PyObject *py_fips_token_description = NULL;
18897     PyObject *py_crypto_slot_description = NULL;
18898     PyObject *py_db_slot_description = NULL;
18899     PyObject *py_fips_slot_description = NULL;
18900 
18901     TraceMethodEnter(self);
18902 
18903     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOOOOOOOOO:InitParameters", kwlist,
18904                                      &py_password_required,
18905                                      &py_min_password_len,
18906                                      &py_manufacturer_id,
18907                                      &py_library_description,
18908                                      &py_crypto_token_description,
18909                                      &py_db_token_description,
18910                                      &py_fips_token_description,
18911                                      &py_crypto_slot_description,
18912                                      &py_db_slot_description,
18913                                      &py_fips_slot_description))
18914         return -1;
18915 
18916     if (py_password_required) {
18917         if (InitParameters_set_password_required(self, py_password_required, NULL) == -1) {
18918             return -1;
18919         }
18920     }
18921 
18922     if (py_min_password_len) {
18923         if (InitParameters_set_min_password_len(self, py_min_password_len, NULL) == -1) {
18924             return -1;
18925         }
18926     }
18927 
18928     if (py_manufacturer_id) {
18929         if (InitParameters_set_manufacturer_id(self, py_manufacturer_id, NULL) == -1) {
18930             return -1;
18931         }
18932     }
18933 
18934     if (py_library_description) {
18935         if (InitParameters_set_library_description(self, py_library_description, NULL) == -1) {
18936             return -1;
18937         }
18938     }
18939 
18940     if (py_crypto_token_description) {
18941         if (InitParameters_set_crypto_token_description(self, py_crypto_token_description, NULL) == -1) {
18942             return -1;
18943         }
18944     }
18945 
18946     if (py_db_token_description) {
18947         if (InitParameters_set_db_token_description(self, py_db_token_description, NULL) == -1) {
18948             return -1;
18949         }
18950     }
18951 
18952     if (py_fips_token_description) {
18953         if (InitParameters_set_fips_token_description(self, py_fips_token_description, NULL) == -1) {
18954             return -1;
18955         }
18956     }
18957 
18958     if (py_crypto_slot_description) {
18959         if (InitParameters_set_crypto_slot_description(self, py_crypto_slot_description, NULL) == -1) {
18960             return -1;
18961         }
18962     }
18963 
18964     if (py_db_slot_description) {
18965         if (InitParameters_set_db_slot_description(self, py_db_slot_description, NULL) == -1) {
18966             return -1;
18967         }
18968     }
18969 
18970     if (py_fips_slot_description) {
18971         if (InitParameters_set_fips_slot_description(self, py_fips_slot_description, NULL) == -1) {
18972             return -1;
18973         }
18974     }
18975 
18976 
18977     return 0;
18978 }
18979 
18980 static PyObject *
InitParameters_str(InitParameters * self)18981 InitParameters_str(InitParameters *self)
18982 {
18983     const char *fmt_str = "password_required=%s, min_password_len=%s, manufacturer_id=%s, library_description=%s, crypto_token_description=%s, db_token_description=%s, fips_token_description=%s, crypto_slot_description=%s, db_slot_description=%s, fips_slot_description=%s";
18984 
18985     PyObject *result = NULL;
18986     PyObject *fmt = NULL;
18987     PyObject *args = NULL;
18988     PyObject *py_password_required = NULL;
18989     PyObject *py_min_password_len = NULL;
18990     PyObject *py_manufacturer_id = NULL;
18991     PyObject *py_library_description = NULL;
18992     PyObject *py_crypto_token_description = NULL;
18993     PyObject *py_db_token_description = NULL;
18994     PyObject *py_fips_token_description = NULL;
18995     PyObject *py_crypto_slot_description = NULL;
18996     PyObject *py_db_slot_description = NULL;
18997     PyObject *py_fips_slot_description = NULL;
18998 
18999     if ((py_password_required = InitParameters_get_password_required(self, NULL)) == NULL) {
19000         goto fail;
19001     }
19002 
19003     if ((py_min_password_len = InitParameters_get_min_password_len(self, NULL)) == NULL) {
19004         goto fail;
19005     }
19006 
19007     if ((py_manufacturer_id = InitParameters_get_manufacturer_id(self, NULL)) == NULL) {
19008         goto fail;
19009     }
19010 
19011     if ((py_library_description = InitParameters_get_library_description(self, NULL)) == NULL) {
19012         goto fail;
19013     }
19014 
19015     if ((py_crypto_token_description = InitParameters_get_crypto_token_description(self, NULL)) == NULL) {
19016         goto fail;
19017     }
19018 
19019     if ((py_db_token_description = InitParameters_get_db_token_description(self, NULL)) == NULL) {
19020         goto fail;
19021     }
19022 
19023     if ((py_fips_token_description = InitParameters_get_fips_token_description(self, NULL)) == NULL) {
19024         goto fail;
19025     }
19026 
19027     if ((py_crypto_slot_description = InitParameters_get_crypto_slot_description(self, NULL)) == NULL) {
19028         goto fail;
19029     }
19030 
19031     if ((py_db_slot_description = InitParameters_get_db_slot_description(self, NULL)) == NULL) {
19032         goto fail;
19033     }
19034 
19035     if ((py_fips_slot_description = InitParameters_get_fips_slot_description(self, NULL)) == NULL) {
19036         goto fail;
19037     }
19038 
19039 
19040     if ((fmt = PyUnicode_FromString(fmt_str)) == NULL) {
19041         goto fail;
19042     }
19043 
19044     if ((args = PyTuple_New(10)) == NULL) {
19045         goto fail;
19046     }
19047 
19048     /*
19049      * We bump the ref count when inserting into the tuple to simpify clean
19050      * up. We always DECREF the variable on exit and also DECREF the
19051      * tuple. When the tuple is deallocated it will DECREF it's members,
19052      * then subsequently we'll individually DECREF the variable, thus
19053      * requiring the INCREF when it's inserted into the tuple.
19054      */
19055     PyTuple_SetItem(args, 0, py_password_required);        Py_INCREF(py_password_required);
19056     PyTuple_SetItem(args, 1, py_min_password_len);         Py_INCREF(py_min_password_len);
19057     PyTuple_SetItem(args, 2, py_manufacturer_id);          Py_INCREF(py_manufacturer_id);
19058     PyTuple_SetItem(args, 3, py_library_description);      Py_INCREF(py_library_description);
19059     PyTuple_SetItem(args, 4, py_crypto_token_description); Py_INCREF(py_crypto_token_description);
19060     PyTuple_SetItem(args, 5, py_db_token_description);     Py_INCREF(py_db_token_description);
19061     PyTuple_SetItem(args, 6, py_fips_token_description);   Py_INCREF(py_fips_token_description);
19062     PyTuple_SetItem(args, 7, py_crypto_slot_description);  Py_INCREF(py_crypto_slot_description);
19063     PyTuple_SetItem(args, 8, py_db_slot_description);      Py_INCREF(py_db_slot_description);
19064     PyTuple_SetItem(args, 9, py_fips_slot_description);    Py_INCREF(py_fips_slot_description);
19065 
19066     if ((result = PyUnicode_Format(fmt, args)) == NULL) {
19067         goto fail;
19068     }
19069 
19070     goto exit;
19071 
19072  fail:
19073     Py_CLEAR(result);
19074  exit:
19075     Py_XDECREF(fmt);
19076     Py_XDECREF(args);
19077     Py_XDECREF(py_password_required);
19078     Py_XDECREF(py_min_password_len);
19079     Py_XDECREF(py_manufacturer_id);
19080     Py_XDECREF(py_library_description);
19081     Py_XDECREF(py_crypto_token_description);
19082     Py_XDECREF(py_db_token_description);
19083     Py_XDECREF(py_fips_token_description);
19084     Py_XDECREF(py_crypto_slot_description);
19085     Py_XDECREF(py_db_slot_description);
19086     Py_XDECREF(py_fips_slot_description);
19087 
19088     return result;
19089 }
19090 
19091 static PyTypeObject InitParametersType = {
19092     PyVarObject_HEAD_INIT(NULL, 0)
19093     "nss.nss.InitParameters",			/* tp_name */
19094     sizeof(InitParameters),			/* tp_basicsize */
19095     0,						/* tp_itemsize */
19096     (destructor)InitParameters_dealloc,		/* tp_dealloc */
19097     0,						/* tp_print */
19098     0,						/* tp_getattr */
19099     0,						/* tp_setattr */
19100     0,						/* tp_compare */
19101     0,						/* tp_repr */
19102     0,						/* tp_as_number */
19103     0,						/* tp_as_sequence */
19104     0,						/* tp_as_mapping */
19105     0,						/* tp_hash */
19106     0,						/* tp_call */
19107     (reprfunc)InitParameters_str,		/* tp_str */
19108     0,						/* tp_getattro */
19109     0,						/* tp_setattro */
19110     0,						/* tp_as_buffer */
19111     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,	/* tp_flags */
19112     InitParameters_doc,				/* tp_doc */
19113     (traverseproc)0,				/* tp_traverse */
19114     (inquiry)0,					/* tp_clear */
19115     0,						/* tp_richcompare */
19116     0,						/* tp_weaklistoffset */
19117     0,						/* tp_iter */
19118     0,						/* tp_iternext */
19119     InitParameters_methods,			/* tp_methods */
19120     InitParameters_members,			/* tp_members */
19121     InitParameters_getseters,			/* tp_getset */
19122     0,						/* tp_base */
19123     0,						/* tp_dict */
19124     0,						/* tp_descr_get */
19125     0,						/* tp_descr_set */
19126     0,						/* tp_dictoffset */
19127     (initproc)InitParameters_init,		/* tp_init */
19128     0,						/* tp_alloc */
19129     InitParameters_new,				/* tp_new */
19130 };
19131 
19132 /* ========================================================================== */
19133 /* =========================== InitContext Class ============================ */
19134 /* ========================================================================== */
19135 
19136 /* ============================== Class Methods ============================= */
19137 
19138 PyDoc_STRVAR(InitContext_shutdown_doc,
19139 "shutdown()\n\
19140 \n\
19141 Shutdown NSS for this context.\n\
19142 ");
19143 
19144 static PyObject *
InitContext_shutdown(InitContext * self)19145 InitContext_shutdown(InitContext* self)
19146 {
19147     TraceMethodEnter(self);
19148 
19149     if (NSS_ShutdownContext(self->context) != SECSuccess) {
19150         return set_nspr_error(NULL);
19151     }
19152 
19153     Py_RETURN_NONE;
19154 }
19155 
19156 
19157 static PyMethodDef InitContext_methods[] = {
19158     {"shutdown", (PyCFunction)InitContext_shutdown,   METH_NOARGS, InitContext_shutdown_doc},
19159     {NULL, NULL}  /* Sentinel */
19160 };
19161 
19162 /* =========================== Class Construction =========================== */
19163 
19164 static PyObject *
InitContext_new(PyTypeObject * type,PyObject * args,PyObject * kwds)19165 InitContext_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
19166 {
19167     InitContext *self;
19168 
19169     TraceObjNewEnter(type);
19170 
19171     if ((self = (InitContext *)type->tp_alloc(type, 0)) == NULL) {
19172         return NULL;
19173     }
19174 
19175     self->context = NULL;
19176 
19177     TraceObjNewLeave(self);
19178     return (PyObject *)self;
19179 }
19180 
19181 static void
InitContext_dealloc(InitContext * self)19182 InitContext_dealloc(InitContext* self)
19183 {
19184     TraceMethodEnter(self);
19185 
19186     /*
19187      * Just in case shutdown_context was not called before the context
19188      * is destroyed we call it here. If the context was already
19189      * shutdown NSS_ShutdownContext will fail with
19190      * SEC_ERROR_NOT_INITIALIZED but we don't bother to check for it.
19191      */
19192     NSS_ShutdownContext(self->context);
19193 
19194     Py_TYPE(self)->tp_free((PyObject*)self);
19195 }
19196 
19197 PyDoc_STRVAR(InitContext_doc,
19198 "An object representing NSSInitContext");
19199 
19200 
19201 static PyTypeObject InitContextType = {
19202     PyVarObject_HEAD_INIT(NULL, 0)
19203     "nss.nss.InitContext",			/* tp_name */
19204     sizeof(InitContext),			/* tp_basicsize */
19205     0,						/* tp_itemsize */
19206     (destructor)InitContext_dealloc,		/* tp_dealloc */
19207     0,						/* tp_print */
19208     0,						/* tp_getattr */
19209     0,						/* tp_setattr */
19210     0,						/* tp_compare */
19211     0,						/* tp_repr */
19212     0,						/* tp_as_number */
19213     0,						/* tp_as_sequence */
19214     0,						/* tp_as_mapping */
19215     0,						/* tp_hash */
19216     0,						/* tp_call */
19217     0,						/* tp_str */
19218     0,						/* tp_getattro */
19219     0,						/* tp_setattro */
19220     0,						/* tp_as_buffer */
19221     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,	/* tp_flags */
19222     InitContext_doc,				/* tp_doc */
19223     (traverseproc)0,				/* tp_traverse */
19224     (inquiry)0,					/* tp_clear */
19225     0,						/* tp_richcompare */
19226     0,						/* tp_weaklistoffset */
19227     0,						/* tp_iter */
19228     0,						/* tp_iternext */
19229     InitContext_methods,			/* tp_methods */
19230     0,						/* tp_members */
19231     0,						/* tp_getset */
19232     0,						/* tp_base */
19233     0,						/* tp_dict */
19234     0,						/* tp_descr_get */
19235     0,						/* tp_descr_set */
19236     0,						/* tp_dictoffset */
19237     0,						/* tp_init */
19238     0,						/* tp_alloc */
19239     0,						/* tp_new */
19240 };
19241 
19242 static PyObject *
InitContext_new_from_NSSInitContext(NSSInitContext * context)19243 InitContext_new_from_NSSInitContext(NSSInitContext *context)
19244 {
19245     InitContext *self = NULL;
19246 
19247     TraceObjNewEnter(NULL);
19248 
19249     if ((self = (InitContext *) InitContext_new(&InitContextType, NULL, NULL)) == NULL) {
19250         return NULL;
19251     }
19252 
19253     self->context = context;
19254 
19255     TraceObjNewLeave(self);
19256     return (PyObject *) self;
19257 }
19258 
19259 /* ========================================================================== */
19260 /* ========================= PKCS12DecodeItem Class ========================= */
19261 /* ========================================================================== */
19262 
19263 /* ============================ Attribute Access ============================ */
19264 
19265 static PyObject *
PKCS12DecodeItem_get_type(PKCS12DecodeItem * self,void * closure)19266 PKCS12DecodeItem_get_type(PKCS12DecodeItem *self, void *closure)
19267 {
19268     TraceMethodEnter(self);
19269 
19270     return PyLong_FromLong(self->type);
19271 }
19272 
19273 static PyObject *
PKCS12DecodeItem_get_has_key(PKCS12DecodeItem * self,void * closure)19274 PKCS12DecodeItem_get_has_key(PKCS12DecodeItem *self, void *closure)
19275 {
19276     TraceMethodEnter(self);
19277 
19278     return PyBool_FromLong(self->has_key);
19279 }
19280 
19281 static PyObject *
PKCS12DecodeItem_get_signed_cert_der(PKCS12DecodeItem * self,void * closure)19282 PKCS12DecodeItem_get_signed_cert_der(PKCS12DecodeItem *self, void *closure)
19283 {
19284     TraceMethodEnter(self);
19285 
19286     Py_INCREF(self->py_signed_cert_der);
19287     return self->py_signed_cert_der;
19288 }
19289 
19290 static PyObject *
PKCS12DecodeItem_get_certificate(PKCS12DecodeItem * self,void * closure)19291 PKCS12DecodeItem_get_certificate(PKCS12DecodeItem *self, void *closure)
19292 {
19293     TraceMethodEnter(self);
19294 
19295     Py_INCREF(self->py_cert);
19296     return self->py_cert;
19297 }
19298 
19299 static PyObject *
PKCS12DecodeItem_get_friendly_name(PKCS12DecodeItem * self,void * closure)19300 PKCS12DecodeItem_get_friendly_name(PKCS12DecodeItem *self, void *closure)
19301 {
19302     TraceMethodEnter(self);
19303 
19304     Py_INCREF(self->py_friendly_name);
19305     return self->py_friendly_name;
19306 }
19307 
19308 static PyObject *
PKCS12DecodeItem_get_shroud_algorithm_id(PKCS12DecodeItem * self,void * closure)19309 PKCS12DecodeItem_get_shroud_algorithm_id(PKCS12DecodeItem *self, void *closure)
19310 {
19311     TraceMethodEnter(self);
19312 
19313     Py_INCREF(self->py_shroud_algorithm_id);
19314     return self->py_shroud_algorithm_id;
19315 }
19316 
19317 static
19318 PyGetSetDef PKCS12DecodeItem_getseters[] = {
19319     {"type",                (getter)PKCS12DecodeItem_get_type,                (setter)NULL, "SEC OID tag indicating what type of PKCS12 item this is", NULL},
19320     {"has_key",             (getter)PKCS12DecodeItem_get_has_key,             (setter)NULL, "boolean indicating if this is a cert with a private key", NULL},
19321     {"signed_cert_der",     (getter)PKCS12DecodeItem_get_signed_cert_der,     (setter)NULL, "signed certificate DER data as SecItem object, or None if does not exist", NULL},
19322     {"certificate",         (getter)PKCS12DecodeItem_get_certificate,         (setter)NULL, "certificate as Certificate object, or None if does not exist", NULL},
19323     {"friendly_name",       (getter)PKCS12DecodeItem_get_friendly_name,       (setter)NULL, "friendly_name as unicode object, or None if does not exist", NULL},
19324     {"shroud_algorithm_id", (getter)PKCS12DecodeItem_get_shroud_algorithm_id, (setter)NULL, "shroud algorithm id certificate as AlgorithmID object, or None if does not exist", NULL},
19325     {NULL}  /* Sentinel */
19326 };
19327 
19328 static PyMemberDef PKCS12DecodeItem_members[] = {
19329     {NULL}  /* Sentinel */
19330 };
19331 
19332 /* ============================== Class Methods ============================= */
19333 
19334 static PyObject *
PKCS12DecodeItem_format_lines(PKCS12DecodeItem * self,PyObject * args,PyObject * kwds)19335 PKCS12DecodeItem_format_lines(PKCS12DecodeItem *self, PyObject *args, PyObject *kwds)
19336 {
19337     static char *kwlist[] = {"level", NULL};
19338     int level = 0;
19339     PyObject *lines = NULL;
19340     PyObject *obj = NULL;
19341 
19342     TraceMethodEnter(self);
19343 
19344     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:format_lines", kwlist, &level))
19345         return NULL;
19346 
19347     if ((lines = PyList_New(0)) == NULL) {
19348         return NULL;
19349     }
19350 
19351     obj = oid_tag_to_pystr_name(self->type);
19352     FMT_OBJ_AND_APPEND(lines, _("Type"), obj, level, fail);
19353     Py_CLEAR(obj);
19354 
19355     switch (self->type) {
19356     case SEC_OID_PKCS12_V1_CERT_BAG_ID:
19357         if (self->has_key) {
19358             FMT_LABEL_AND_APPEND(lines, _("Certificate (has private key)"), level, fail);
19359         } else {
19360             FMT_LABEL_AND_APPEND(lines, _("Certificate"), level, fail);
19361         }
19362         FMT_OBJ_AND_APPEND(lines, NULL, self->py_cert, level+1, fail);
19363         obj = SignedData_new_from_SECItem(&((SecItem *)self->py_signed_cert_der)->item);
19364         FMT_OBJ_AND_APPEND(lines, _("Signature"), obj, level, fail);
19365         Py_CLEAR(obj);
19366 
19367         FMT_OBJ_AND_APPEND(lines, _("Friendly Name"), self->py_friendly_name, level, fail);
19368         FMT_OBJ_AND_APPEND(lines, _("Encryption algorithm"), self->py_shroud_algorithm_id, level, fail);
19369         break;
19370     case SEC_OID_PKCS12_V1_KEY_BAG_ID:
19371     case SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID:
19372         if (self->type == SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID) {
19373             FMT_LABEL_AND_APPEND(lines, _("Key (shrouded)"), level, fail);
19374         } else {
19375             FMT_LABEL_AND_APPEND(lines, _("Key"), level, fail);
19376         }
19377         FMT_OBJ_AND_APPEND(lines, _("Friendly Name"), self->py_friendly_name, level, fail);
19378         FMT_OBJ_AND_APPEND(lines, _("Encryption algorithm"), self->py_shroud_algorithm_id, level, fail);
19379         break;
19380     default:
19381         FMT_LABEL_AND_APPEND(lines, _("unknown bag type"), level, fail);
19382         break;
19383     }
19384 
19385     return lines;
19386  fail:
19387     Py_XDECREF(obj);
19388     Py_XDECREF(lines);
19389     return NULL;
19390 }
19391 
19392 static PyObject *
PKCS12DecodeItem_format(PKCS12DecodeItem * self,PyObject * args,PyObject * kwds)19393 PKCS12DecodeItem_format(PKCS12DecodeItem *self, PyObject *args, PyObject *kwds)
19394 {
19395     TraceMethodEnter(self);
19396 
19397     return format_from_lines((format_lines_func)PKCS12DecodeItem_format_lines, (PyObject *)self, args, kwds);
19398 }
19399 
19400 static PyObject *
PKCS12DecodeItem_str(PKCS12DecodeItem * self)19401 PKCS12DecodeItem_str(PKCS12DecodeItem *self)
19402 {
19403     PyObject *py_formatted_result = NULL;
19404 
19405     TraceMethodEnter(self);
19406 
19407     py_formatted_result =  PKCS12DecodeItem_format(self, empty_tuple, NULL);
19408     return py_formatted_result;
19409 
19410 }
19411 
19412 static PyMethodDef PKCS12DecodeItem_methods[] = {
19413     {"format_lines", (PyCFunction)PKCS12DecodeItem_format_lines,   METH_VARARGS|METH_KEYWORDS, generic_format_lines_doc},
19414     {"format",       (PyCFunction)PKCS12DecodeItem_format,         METH_VARARGS|METH_KEYWORDS, generic_format_doc},
19415     {NULL, NULL}  /* Sentinel */
19416 };
19417 
19418 /* =========================== Class Construction =========================== */
19419 
19420 static PyObject *
PKCS12DecodeItem_new(PyTypeObject * type,PyObject * args,PyObject * kwds)19421 PKCS12DecodeItem_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
19422 {
19423     PKCS12DecodeItem *self;
19424 
19425     TraceObjNewEnter(type);
19426 
19427     if ((self = (PKCS12DecodeItem *)type->tp_alloc(type, 0)) == NULL) {
19428         return NULL;
19429     }
19430 
19431     self->type                   = SEC_OID_UNKNOWN;
19432     self->has_key                = PR_FALSE;
19433     self->py_signed_cert_der     = NULL;
19434     self->py_cert                = NULL;
19435     self->py_friendly_name       = NULL;
19436     self->py_shroud_algorithm_id = NULL;
19437 
19438     TraceObjNewLeave(self);
19439     return (PyObject *)self;
19440 }
19441 
19442 static int
PKCS12DecodeItem_traverse(PKCS12DecodeItem * self,visitproc visit,void * arg)19443 PKCS12DecodeItem_traverse(PKCS12DecodeItem *self, visitproc visit, void *arg)
19444 {
19445     TraceMethodEnter(self);
19446 
19447     Py_VISIT(self->py_signed_cert_der);
19448     Py_VISIT(self->py_cert);
19449     Py_VISIT(self->py_friendly_name);
19450     Py_VISIT(self->py_shroud_algorithm_id);
19451     return 0;
19452 }
19453 
19454 static int
PKCS12DecodeItem_clear(PKCS12DecodeItem * self)19455 PKCS12DecodeItem_clear(PKCS12DecodeItem* self)
19456 {
19457     TraceMethodEnter(self);
19458 
19459     Py_CLEAR(self->py_signed_cert_der);
19460     Py_CLEAR(self->py_cert);
19461     Py_CLEAR(self->py_friendly_name);
19462     Py_CLEAR(self->py_shroud_algorithm_id);
19463     return 0;
19464 }
19465 
19466 static void
PKCS12DecodeItem_dealloc(PKCS12DecodeItem * self)19467 PKCS12DecodeItem_dealloc(PKCS12DecodeItem* self)
19468 {
19469     TraceMethodEnter(self);
19470 
19471     PKCS12DecodeItem_clear(self);
19472     Py_TYPE(self)->tp_free((PyObject*)self);
19473 }
19474 
19475 PyDoc_STRVAR(PKCS12DecodeItem_doc,
19476 "An object representing an item in a PKCS12 collection.\n\
19477 Also known as a \"bag\"");
19478 
19479 static int
PKCS12DecodeItem_init(PKCS12DecodeItem * self,PyObject * args,PyObject * kwds)19480 PKCS12DecodeItem_init(PKCS12DecodeItem *self, PyObject *args, PyObject *kwds)
19481 {
19482     static char *kwlist[] = {"arg", NULL};
19483     PyObject *arg;
19484 
19485     TraceMethodEnter(self);
19486 
19487     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|i:PKCS12DecodeItem", kwlist,
19488                                      &arg))
19489         return -1;
19490 
19491     return 0;
19492 }
19493 
19494 static PyTypeObject PKCS12DecodeItemType = {
19495     PyVarObject_HEAD_INIT(NULL, 0)
19496     "nss.nss.PKCS12DecodeItem",			/* tp_name */
19497     sizeof(PKCS12DecodeItem),			/* tp_basicsize */
19498     0,						/* tp_itemsize */
19499     (destructor)PKCS12DecodeItem_dealloc,	/* tp_dealloc */
19500     0,						/* tp_print */
19501     0,						/* tp_getattr */
19502     0,						/* tp_setattr */
19503     0,						/* tp_compare */
19504     0,						/* tp_repr */
19505     0,						/* tp_as_number */
19506     0,						/* tp_as_sequence */
19507     0,						/* tp_as_mapping */
19508     0,						/* tp_hash */
19509     0,						/* tp_call */
19510     (reprfunc)PKCS12DecodeItem_str,		/* tp_str */
19511     0,						/* tp_getattro */
19512     0,						/* tp_setattro */
19513     0,						/* tp_as_buffer */
19514     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,	/* tp_flags */
19515     PKCS12DecodeItem_doc,			/* tp_doc */
19516     (traverseproc)PKCS12DecodeItem_traverse,	/* tp_traverse */
19517     (inquiry)PKCS12DecodeItem_clear,		/* tp_clear */
19518     0,						/* tp_richcompare */
19519     0,						/* tp_weaklistoffset */
19520     0,						/* tp_iter */
19521     0,						/* tp_iternext */
19522     PKCS12DecodeItem_methods,			/* tp_methods */
19523     PKCS12DecodeItem_members,			/* tp_members */
19524     PKCS12DecodeItem_getseters,			/* tp_getset */
19525     0,						/* tp_base */
19526     0,						/* tp_dict */
19527     0,						/* tp_descr_get */
19528     0,						/* tp_descr_set */
19529     0,						/* tp_dictoffset */
19530     (initproc)PKCS12DecodeItem_init,		/* tp_init */
19531     0,						/* tp_alloc */
19532     PKCS12DecodeItem_new,			/* tp_new */
19533 };
19534 
19535 static PyObject *
PKCS12DecodeItem_new_from_SEC_PKCS12DecoderItem(const SEC_PKCS12DecoderItem * item)19536 PKCS12DecodeItem_new_from_SEC_PKCS12DecoderItem(const SEC_PKCS12DecoderItem *item)
19537 {
19538     PKCS12DecodeItem *self = NULL;
19539 
19540     TraceObjNewEnter(NULL);
19541 
19542     if ((self = (PKCS12DecodeItem *) PKCS12DecodeItemType.tp_new(&PKCS12DecodeItemType, NULL, NULL)) == NULL) {
19543         return NULL;
19544     }
19545 
19546     self->type = item->type;
19547     self->has_key = item->hasKey;
19548 
19549     if (item->der) {
19550         if ((self->py_signed_cert_der = SecItem_new_from_SECItem(item->der, SECITEM_signed_data)) == NULL) {
19551             Py_CLEAR(self);
19552             return NULL;
19553         }
19554     } else {
19555         self->py_signed_cert_der = Py_None;
19556         Py_INCREF(self->py_signed_cert_der);
19557     }
19558 
19559     if (item->friendlyName) {
19560         if ((self->py_friendly_name = PyUnicode_DecodeUTF8((const char *)item->friendlyName->data,
19561                                                            item->friendlyName->len, NULL)) == NULL) {
19562             Py_CLEAR(self);
19563             return NULL;
19564         }
19565     } else {
19566         self->py_friendly_name = Py_None;
19567         Py_INCREF(self->py_friendly_name);
19568     }
19569 
19570     if (item->shroudAlg) {
19571         if ((self->py_shroud_algorithm_id = AlgorithmID_new_from_SECAlgorithmID(item->shroudAlg)) == NULL) {
19572             Py_CLEAR(self);
19573             return NULL;
19574         }
19575     } else {
19576         self->py_shroud_algorithm_id = Py_None;
19577         Py_INCREF(self->py_shroud_algorithm_id);
19578     }
19579 
19580     if (item->type == SEC_OID_PKCS12_V1_CERT_BAG_ID) {
19581         if ((self->py_cert = Certificate_new_from_signed_der_secitem(item->der)) == NULL) {
19582             Py_CLEAR(self);
19583             return NULL;
19584         }
19585     } else {
19586         self->py_cert = Py_None;
19587         Py_INCREF(self->py_cert);
19588     }
19589 
19590     TraceObjNewLeave(self);
19591     return (PyObject *) self;
19592 }
19593 
19594 /* ========================================================================== */
19595 /* ========================== PKCS12Decoder Class =========================== */
19596 /* ========================================================================== */
19597 
19598 static SECItem *
PKCS12_default_nickname_collision_callback(SECItem * old_nickname,PRBool * returned_cancel,void * arg)19599 PKCS12_default_nickname_collision_callback(SECItem *old_nickname, PRBool *returned_cancel, void *arg)
19600 {
19601     char *nickname     = NULL;
19602     SECItem *returned_nickname = NULL;
19603     CERTCertificate* cert = (CERTCertificate*)arg;
19604 
19605     if (!returned_cancel || !cert) {
19606 	return NULL;
19607     }
19608 
19609     if ((nickname = CERT_MakeCANickname(cert)) == NULL) {
19610     	return NULL;
19611     }
19612 
19613     if (old_nickname && old_nickname->data && old_nickname->len &&
19614        PORT_Strlen(nickname) == old_nickname->len &&
19615        PORT_Strncmp((char *)old_nickname->data, nickname, old_nickname->len) == 0) {
19616 	PORT_Free(nickname);
19617 	PORT_SetError(SEC_ERROR_CERT_NICKNAME_COLLISION);
19618         PySys_WriteStderr("PKCS12_default_nickname_collision_callback: CERT_MakeCANickname() returned existing nickname\n");
19619 	return NULL;
19620     }
19621 
19622     if ((returned_nickname = PORT_ZNew(SECItem)) == NULL) {
19623 	PORT_Free(nickname);
19624 	return NULL;
19625     }
19626 
19627     returned_nickname->data = (unsigned char *)nickname;
19628     returned_nickname->len = PORT_Strlen(nickname);
19629 
19630     return returned_nickname;
19631 }
19632 
19633 static SECItem *
PKCS12_nickname_collision_callback(SECItem * old_nickname,PRBool * returned_cancel,void * arg)19634 PKCS12_nickname_collision_callback(SECItem *old_nickname, PRBool *returned_cancel, void *arg)
19635 {
19636     CERTCertificate* cert = NULL;
19637     PyGILState_STATE gstate;
19638     PyObject *nickname_collision_callback = NULL;
19639     PyObject *py_old_nickname = NULL;
19640     PyObject *py_cert = NULL;
19641     PyObject *result = NULL;
19642     PyObject *new_args = NULL;
19643     PyObject *py_new_nickname = NULL;
19644     PyObject *py_new_nickname_utf8 = NULL;
19645     PRBool cancel = PR_TRUE;
19646     PyObject *py_cancel = NULL;
19647     SECItem *returned_nickname = NULL;
19648 
19649     gstate = PyGILState_Ensure();
19650 
19651     TraceMessage("PKCS12_nickname_collision_callback: enter");
19652 
19653     if ((nickname_collision_callback = get_thread_local("nickname_collision_callback")) == NULL) {
19654         if (!PyErr_Occurred()) {
19655             PySys_WriteStderr("PKCS12 nickname collision callback undefined\n");
19656         } else {
19657             PyErr_Print();
19658         }
19659 	PyGILState_Release(gstate);
19660         return NULL;
19661     }
19662 
19663     if (!old_nickname || !old_nickname->len || !old_nickname->data) {
19664         py_old_nickname = Py_None;
19665         Py_INCREF(py_old_nickname);
19666     } else {
19667         py_old_nickname = PyUnicode_FromStringAndSize((char *)old_nickname->data, old_nickname->len);
19668     }
19669 
19670     cert = (CERTCertificate*)arg;
19671     if ((py_cert = Certificate_new_from_CERTCertificate(cert, true)) == NULL) {
19672         Py_DECREF(py_old_nickname);
19673         return NULL;
19674     }
19675 
19676     if ((new_args = PyTuple_New(2)) == NULL) {
19677         PySys_WriteStderr("PKCS12 nickname collision callback: out of memory\n");
19678         goto exit;
19679     }
19680 
19681     PyTuple_SetItem(new_args, 0, py_old_nickname);
19682     PyTuple_SetItem(new_args, 1, py_cert);
19683 
19684     if ((result = PyObject_CallObject(nickname_collision_callback, new_args)) == NULL) {
19685         PySys_WriteStderr("exception in PKCS12 nickname collision callback\n");
19686         PyErr_Print();  /* this also clears the error */
19687         goto exit;
19688     }
19689 
19690     if (!PyTuple_Check(result) || PyTuple_Size(result) != 2) {
19691         PySys_WriteStderr("Error, PKCS12 nickname collision callback expected tuple result with 2 values.\n");
19692         goto exit;
19693     }
19694 
19695     py_new_nickname = PyTuple_GetItem(result, 0);
19696     py_cancel       = PyTuple_GetItem(result, 1);
19697 
19698     if (!(PyBaseString_Check(py_new_nickname) || PyNone_Check(py_new_nickname))) {
19699         PySys_WriteStderr("Error, PKCS12 nickname collision callback expected 1st returned item to be string or None.\n");
19700         goto exit;
19701     }
19702 
19703     if (PyBool_Check(py_cancel)) {
19704         cancel = PyBoolAsPRBool(py_cancel);
19705     } else {
19706         PySys_WriteStderr("Error, PKCS12 nickname collision callback expected 2nd returned item to be boolean.\n");
19707         goto exit;
19708     }
19709 
19710     if (PyBaseString_Check(py_new_nickname)) {
19711         py_new_nickname_utf8 = PyBaseString_UTF8(py_new_nickname, "new nickname");
19712 
19713         if ((returned_nickname = PORT_New(SECItem)) == NULL) {
19714             PyErr_NoMemory();
19715             goto exit;
19716         }
19717 
19718         returned_nickname->data = (unsigned char *)PORT_Strdup(PyBytes_AsString(py_new_nickname_utf8));
19719         returned_nickname->len = PyBytes_Size(py_new_nickname_utf8);
19720     }
19721 
19722 
19723  exit:
19724     TraceMessage("PKCS12_nickname_collision_callback: exiting");
19725 
19726     Py_XDECREF(new_args);
19727     Py_XDECREF(result);
19728     Py_XDECREF(py_new_nickname_utf8);
19729 
19730     PyGILState_Release(gstate);
19731 
19732     *returned_cancel = cancel;
19733     return returned_nickname;
19734 }
19735 
19736 PyDoc_STRVAR(PKCS12_pkcs12_set_nickname_collision_callback_doc,
19737 "pkcs12_set_nickname_collision_callback(callback)\n\
19738 \n\
19739 :Parameters:\n\
19740     callback : function pointer\n\
19741         The callback function\n\
19742 \n\
19743 When importing a certificate via a `PKCS12Decoder` object and the\n\
19744 nickname is not set or collides with an existing nickname in the NSS\n\
19745 database then this callback is invoked to resolve the problem. If no\n\
19746 nickname collision callback has been set then an internal default\n\
19747 callback will be used instead which calls the NSS function CERT_MakeCANickname\n\
19748 (available in the Python binding as `Certificate.make_ca_nickname()`).\n\
19749 \n\
19750 The callback has the signature::\n\
19751     \n\
19752     nickname_collision_callback(old_nickname, cert) --> new_nickname, cancel\n\
19753 \n\
19754 old_nickname\n\
19755     the preious nickname or None if previous did not exist\n\
19756 cert\n\
19757     the `Certificate` object being imported.\n\
19758 \n\
19759 The callback returns 2 values, the new nickname, and a boolean.\n\
19760 \n\
19761     new_nickname\n\
19762         The new nickname to try or None\n\
19763 \n\
19764     cancel\n\
19765         boolean indicating if collision resolution should be cancelled\n\
19766 \n\
19767 ");
19768 
19769 static PyObject *
PKCS12_pkcs12_set_nickname_collision_callback(PyObject * self,PyObject * args)19770 PKCS12_pkcs12_set_nickname_collision_callback(PyObject *self, PyObject *args)
19771 {
19772     PyObject *callback;
19773 
19774     TraceMethodEnter(self);
19775 
19776     if (!PyArg_ParseTuple(args, "O:pkcs12_set_nickname_collision_callback", &callback)) {
19777         return NULL;
19778     }
19779 
19780     if (!PyCallable_Check(callback)) {
19781         PyErr_SetString(PyExc_TypeError, "callback must be callable");
19782         return NULL;
19783     }
19784 
19785     if (set_thread_local("nickname_collision_callback", callback) < 0) {
19786         return NULL;
19787     }
19788 
19789     Py_RETURN_NONE;
19790 }
19791 
19792 /* ============================ Attribute Access ============================ */
19793 
19794 static
19795 PyGetSetDef PKCS12Decoder_getseters[] = {
19796     {NULL}  /* Sentinel */
19797 };
19798 
19799 static PyMemberDef PKCS12Decoder_members[] = {
19800     {NULL}  /* Sentinel */
19801 };
19802 
19803 /* ============================== Class Methods ============================= */
19804 
19805 PyDoc_STRVAR(PKCS12Decoder_database_import_doc,
19806 "import()\n\
19807 \n\
19808 Import the contents of the `PKCS12Decoder` object into the current NSS database.\n\
19809 \n\
19810 During import if the certificate(s) in the `PKCS12Decoder` object does\n\
19811 not have a nickname or there is a collision with an existing nickname\n\
19812 then a callback will be invoked to provide a new nickname. See\n\
19813 `pkcs12_set_nickname_collision_callback`.\n\
19814 \n\
19815 ");
19816 
19817 static PyObject *
PKCS12Decoder_database_import(PKCS12Decoder * self,PyObject * args)19818 PKCS12Decoder_database_import(PKCS12Decoder *self, PyObject *args)
19819 {
19820     SEC_PKCS12NicknameCollisionCallback nickname_callback = NULL;
19821 
19822     TraceMethodEnter(self);
19823 
19824     if (get_thread_local("nickname_collision_callback") == NULL) {
19825         nickname_callback = PKCS12_default_nickname_collision_callback;
19826     } else {
19827         nickname_callback = PKCS12_nickname_collision_callback;
19828     }
19829 
19830     if (SEC_PKCS12DecoderValidateBags(self->decoder_ctx, nickname_callback) != SECSuccess) {
19831         return set_nspr_error("PKCS12 decode validate bags failed");
19832     }
19833 
19834     if (SEC_PKCS12DecoderImportBags(self->decoder_ctx) != SECSuccess) {
19835         return set_nspr_error("PKCS12 decode import bags failed");
19836     }
19837 
19838     Py_RETURN_NONE;
19839 }
19840 
19841 static PyObject *
PKCS12Decoder_format_lines(PKCS12Decoder * self,PyObject * args,PyObject * kwds)19842 PKCS12Decoder_format_lines(PKCS12Decoder *self, PyObject *args, PyObject *kwds)
19843 {
19844     static char *kwlist[] = {"level", NULL};
19845     int level = 0;
19846     PyObject *lines = NULL;
19847     char *msg = NULL;
19848     PyObject *obj = NULL;
19849     Py_ssize_t i, n_items;
19850 
19851     TraceMethodEnter(self);
19852 
19853     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:format_lines", kwlist, &level))
19854         return NULL;
19855 
19856     if ((lines = PyList_New(0)) == NULL) {
19857         return NULL;
19858     }
19859 
19860     n_items = PyTuple_Size(self->py_decode_items);
19861 
19862     msg = PR_smprintf(_("%d PKCS12 Decode Items"), n_items);
19863     FMT_LABEL_AND_APPEND(lines, msg, level, fail);
19864     PR_smprintf_free(msg);
19865 
19866     for (i = 0; i < n_items; i++) {
19867         msg = PR_smprintf(_("Item %d"), i+1);
19868         FMT_LABEL_AND_APPEND(lines, msg, level, fail);
19869         PR_smprintf_free(msg);
19870 
19871         obj = PKCS12Decoder_item(self, i);
19872         CALL_FORMAT_LINES_AND_APPEND(lines, obj, level+1, fail);
19873         Py_CLEAR(obj);
19874 
19875         if (i < n_items-1) {    /* blank separator line */
19876             FMT_LABEL_AND_APPEND(lines, NULL, level, fail);
19877         }
19878 
19879     }
19880 
19881     return lines;
19882  fail:
19883     Py_XDECREF(obj);
19884     Py_XDECREF(lines);
19885     return NULL;
19886 }
19887 
19888 static PyObject *
PKCS12Decoder_format(PKCS12Decoder * self,PyObject * args,PyObject * kwds)19889 PKCS12Decoder_format(PKCS12Decoder *self, PyObject *args, PyObject *kwds)
19890 {
19891     TraceMethodEnter(self);
19892 
19893     return format_from_lines((format_lines_func)PKCS12Decoder_format_lines, (PyObject *)self, args, kwds);
19894 }
19895 
19896 static PyObject *
PKCS12Decoder_str(PKCS12Decoder * self)19897 PKCS12Decoder_str(PKCS12Decoder *self)
19898 {
19899     PyObject *py_formatted_result = NULL;
19900 
19901     TraceMethodEnter(self);
19902 
19903     py_formatted_result =  PKCS12Decoder_format(self, empty_tuple, NULL);
19904     return py_formatted_result;
19905 
19906 }
19907 
19908 static PyMethodDef PKCS12Decoder_methods[] = {
19909     {"database_import", (PyCFunction)PKCS12Decoder_database_import, METH_NOARGS,                PKCS12Decoder_database_import_doc},
19910     {"format_lines",    (PyCFunction)PKCS12Decoder_format_lines,    METH_VARARGS|METH_KEYWORDS, generic_format_lines_doc},
19911     {"format",          (PyCFunction)PKCS12Decoder_format,          METH_VARARGS|METH_KEYWORDS, generic_format_doc},
19912     {NULL, NULL}  /* Sentinel */
19913 };
19914 
19915 /* =========================== Sequence Protocol ============================ */
19916 
19917 static Py_ssize_t
PKCS12Decoder_length(PKCS12Decoder * self)19918 PKCS12Decoder_length(PKCS12Decoder *self)
19919 {
19920     if (!self->py_decode_items) return 0;
19921     return PyTuple_Size(self->py_decode_items);
19922 }
19923 
19924 static PyObject *
PKCS12Decoder_item(PKCS12Decoder * self,register Py_ssize_t i)19925 PKCS12Decoder_item(PKCS12Decoder *self, register Py_ssize_t i)
19926 {
19927     PyObject *py_decode_item = NULL;
19928 
19929     if (!self->py_decode_items) {
19930         return PyErr_Format(PyExc_ValueError, "%s is uninitialized", Py_TYPE(self)->tp_name);
19931     }
19932     py_decode_item = PyTuple_GetItem(self->py_decode_items, i);
19933     Py_XINCREF(py_decode_item);
19934     return py_decode_item;
19935 }
19936 
19937 /* =========================== Class Construction =========================== */
19938 
19939 static PyObject *
PKCS12Decoder_new(PyTypeObject * type,PyObject * args,PyObject * kwds)19940 PKCS12Decoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
19941 {
19942     PKCS12Decoder *self;
19943 
19944     TraceObjNewEnter(type);
19945 
19946     if ((self = (PKCS12Decoder *)type->tp_alloc(type, 0)) == NULL) {
19947         return NULL;
19948     }
19949 
19950     self->ucs2_password_item = NULL;
19951     self->decoder_ctx = NULL;
19952     self->py_decode_items = NULL;
19953 
19954     TraceObjNewLeave(self);
19955     return (PyObject *)self;
19956 }
19957 
19958 static int
PKCS12Decoder_traverse(PKCS12Decoder * self,visitproc visit,void * arg)19959 PKCS12Decoder_traverse(PKCS12Decoder *self, visitproc visit, void *arg)
19960 {
19961     TraceMethodEnter(self);
19962 
19963     Py_VISIT(self->py_decode_items);
19964     return 0;
19965 }
19966 
19967 static int
PKCS12Decoder_clear(PKCS12Decoder * self)19968 PKCS12Decoder_clear(PKCS12Decoder* self)
19969 {
19970     TraceMethodEnter(self);
19971 
19972     Py_CLEAR(self->py_decode_items);
19973     return 0;
19974 }
19975 
19976 static void
PKCS12Decoder_dealloc(PKCS12Decoder * self)19977 PKCS12Decoder_dealloc(PKCS12Decoder* self)
19978 {
19979     TraceMethodEnter(self);
19980 
19981     if (self->ucs2_password_item) {
19982         SECITEM_ZfreeItem(self->ucs2_password_item, PR_TRUE);
19983     }
19984     if (self->decoder_ctx) {
19985 	SEC_PKCS12DecoderFinish(self->decoder_ctx);
19986     }
19987 
19988     PKCS12Decoder_clear(self);
19989     Py_TYPE(self)->tp_free((PyObject*)self);
19990 }
19991 
19992 PyDoc_STRVAR(PKCS12Decoder_doc,
19993 "PKCS12Decoder(file, password, slot=None)\n\
19994 \n\
19995 :Parameters:\n\
19996     file : file name or file object\n\
19997         pkcs12 input data.\n\
19998 \n\
19999             * If string treat as file path to open and read.\n\
20000             * If file object read from the file object.\n\
20001     password : string\n\
20002         The password protecting the PKCS12 contents\n\
20003     slot : `PK11Slot` object\n\
20004         The PK11 slot to use. If None defaults to internal\n\
20005         slot, see `nss.get_internal_key_slot()`\n\
20006 \n\
20007 ");
20008 
20009 static int
PKCS12Decoder_init(PKCS12Decoder * self,PyObject * args,PyObject * kwds)20010 PKCS12Decoder_init(PKCS12Decoder *self, PyObject *args, PyObject *kwds)
20011 {
20012     static char *kwlist[] = {"file", "password", "slot", NULL};
20013     PyObject *file_arg = NULL;
20014     PyObject *py_file_contents = NULL;
20015     PyObject *py_slot = Py_None;
20016     char *utf8_password = NULL;
20017     size_t utf8_password_len = 0;
20018     unsigned int ucs2_password_alloc_len = 0;
20019 
20020     char *slot_password = NULL;
20021     PK11SlotInfo *slot = NULL;
20022     int num_decode_items = 0;
20023     const SEC_PKCS12DecoderItem *decoder_item = NULL;
20024     PyObject *py_decode_item = NULL;
20025     int item_idx;
20026     int result = 0;
20027 
20028     TraceMethodEnter(self);
20029 
20030     if (!PyArg_ParseTupleAndKeywords(args, kwds, "Oes|O&:PKCS12Decoder", kwlist,
20031                                      &file_arg, "utf-8", &utf8_password,
20032                                      PK11SlotOrNoneConvert, &py_slot)) {
20033         return -1;
20034     }
20035 
20036 
20037     if ((py_file_contents = read_data_from_file(file_arg, "rb")) == NULL) {
20038         result = -1;
20039         goto exit;
20040     }
20041 
20042     if (!PyBytes_Check(py_file_contents)) {
20043         PyErr_Format(PyExc_TypeError, "expected file contents to be bytes, not %.200s",
20044                      Py_TYPE(py_file_contents)->tp_name);
20045 
20046         result = -1;
20047         goto exit;
20048     }
20049 
20050     /*
20051      * The +1 for the utf8 password is for the null terminator which is used
20052      * in the computation of the symetric key. Therefore the conversion to
20053      * ucs2 must include the null terminator. It's safe for us to read the
20054      * null terminator at the end of the string Python provides because Python
20055      * always provides a 1 byte null terminator for all of it's string allocations.
20056      */
20057     utf8_password_len = strlen(utf8_password) + 1;
20058     ucs2_password_alloc_len = utf8_password_len * 2;
20059 
20060     if ((self->ucs2_password_item =
20061          SECITEM_AllocItem(NULL, NULL, ucs2_password_alloc_len)) == NULL) {
20062         set_nspr_error(NULL);
20063         result = -1;
20064         goto exit;
20065     }
20066 
20067     if (!PORT_UCS2_UTF8Conversion(PR_TRUE, (unsigned char *)utf8_password, utf8_password_len,
20068                                   self->ucs2_password_item->data, ucs2_password_alloc_len,
20069                                   &self->ucs2_password_item->len)) {
20070         PyErr_SetString(PyExc_ValueError, "password conversion to UCS2 failed");
20071         result = -1;
20072         goto exit;
20073     }
20074 
20075     if (PyNone_Check(py_slot)) {
20076 	slot = PK11_GetInternalKeySlot();
20077     } else {
20078         slot = ((PK11Slot *)py_slot)->slot;
20079     }
20080 
20081     if ((self->decoder_ctx = SEC_PKCS12DecoderStart(self->ucs2_password_item,
20082                                          slot,
20083                                          slot_password,
20084                                          NULL, NULL, NULL, NULL, NULL)) == NULL) {
20085         set_nspr_error("PKCS12 decoder start failed");
20086         result = -1;
20087         goto exit;
20088     }
20089 
20090     /* decode the item */
20091     if (SEC_PKCS12DecoderUpdate(self->decoder_ctx,
20092                                 (unsigned char *)PyBytes_AS_STRING(py_file_contents),
20093                                 PyBytes_GET_SIZE(py_file_contents)) != SECSuccess) {
20094         set_nspr_error("PKCS12 decoding failed");
20095         result = -1;
20096         goto exit;
20097     }
20098 
20099     /* does the blob authenticate properly? */
20100     if ((SEC_PKCS12DecoderVerify(self->decoder_ctx) != SECSuccess)) {
20101         set_nspr_error("PKCS12 decode not verified");
20102         result = -1;
20103         goto exit;
20104     }
20105 
20106     if (SEC_PKCS12DecoderIterateInit(self->decoder_ctx) != SECSuccess) {
20107         set_nspr_error("PKCS12 item iteration failed");
20108         result = -1;
20109         goto exit;
20110     }
20111 
20112     num_decode_items = 0;
20113     while (SEC_PKCS12DecoderIterateNext(self->decoder_ctx, &decoder_item) == SECSuccess) {
20114         num_decode_items++;
20115     }
20116     if ((self->py_decode_items = PyTuple_New(num_decode_items)) == NULL) {
20117         result = -1;
20118         goto exit;
20119     }
20120 
20121     if (SEC_PKCS12DecoderIterateInit(self->decoder_ctx) != SECSuccess) {
20122         set_nspr_error("PKCS12 item iteration failed");
20123         result = -1;
20124         goto exit;
20125     }
20126 
20127     for (item_idx = 0;
20128          SEC_PKCS12DecoderIterateNext(self->decoder_ctx, &decoder_item) == SECSuccess;
20129          item_idx++) {
20130         if ((py_decode_item = PKCS12DecodeItem_new_from_SEC_PKCS12DecoderItem(decoder_item)) == NULL) {
20131             result = -1;
20132             goto exit;
20133         }
20134         PyTuple_SetItem(self->py_decode_items, item_idx, py_decode_item);
20135     }
20136 
20137  exit:
20138     if (!py_slot && slot) {
20139     	PK11_FreeSlot(slot);
20140     }
20141 
20142     if (utf8_password)
20143         PyMem_Free(utf8_password);
20144     if (py_file_contents)
20145         Py_DECREF(py_file_contents);
20146 
20147     return result;
20148 }
20149 
20150 static PySequenceMethods PKCS12Decoder_as_sequence = {
20151     (lenfunc)PKCS12Decoder_length,		/* sq_length */
20152     0,						/* sq_concat */
20153     0,						/* sq_repeat */
20154     (ssizeargfunc)PKCS12Decoder_item,		/* sq_item */
20155     0,						/* sq_slice */
20156     0,						/* sq_ass_item */
20157     0,						/* sq_ass_slice */
20158     0,						/* sq_contains */
20159     0,						/* sq_inplace_concat */
20160     0,						/* sq_inplace_repeat */
20161 };
20162 
20163 static PyTypeObject PKCS12DecoderType = {
20164     PyVarObject_HEAD_INIT(NULL, 0)
20165     "nss.nss.PKCS12Decoder",			/* tp_name */
20166     sizeof(PKCS12Decoder),			/* tp_basicsize */
20167     0,						/* tp_itemsize */
20168     (destructor)PKCS12Decoder_dealloc,		/* tp_dealloc */
20169     0,						/* tp_print */
20170     0,						/* tp_getattr */
20171     0,						/* tp_setattr */
20172     0,						/* tp_compare */
20173     0,						/* tp_repr */
20174     0,						/* tp_as_number */
20175     &PKCS12Decoder_as_sequence,			/* tp_as_sequence */
20176     0,						/* tp_as_mapping */
20177     0,						/* tp_hash */
20178     0,						/* tp_call */
20179     (reprfunc)PKCS12Decoder_str,		/* tp_str */
20180     0,						/* tp_getattro */
20181     0,						/* tp_setattro */
20182     0,						/* tp_as_buffer */
20183     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,	/* tp_flags */
20184     PKCS12Decoder_doc,				/* tp_doc */
20185     (traverseproc)PKCS12Decoder_traverse,	/* tp_traverse */
20186     (inquiry)PKCS12Decoder_clear,		/* tp_clear */
20187     0,						/* tp_richcompare */
20188     0,						/* tp_weaklistoffset */
20189     0,						/* tp_iter */
20190     0,						/* tp_iternext */
20191     PKCS12Decoder_methods,			/* tp_methods */
20192     PKCS12Decoder_members,			/* tp_members */
20193     PKCS12Decoder_getseters,			/* tp_getset */
20194     0,						/* tp_base */
20195     0,						/* tp_dict */
20196     0,						/* tp_descr_get */
20197     0,						/* tp_descr_set */
20198     0,						/* tp_dictoffset */
20199     (initproc)PKCS12Decoder_init,		/* tp_init */
20200     0,						/* tp_alloc */
20201     PKCS12Decoder_new,				/* tp_new */
20202 };
20203 
20204 
20205 /* ========================================================================== */
20206 /* ======================== CertVerifyLogNode Class ========================= */
20207 /* ========================================================================== */
20208 
20209 /* ============================ Attribute Access ============================ */
20210 
20211 static PyObject *
CertVerifyLogNode_get_certificate(CertVerifyLogNode * self,void * closure)20212 CertVerifyLogNode_get_certificate(CertVerifyLogNode *self, void *closure)
20213 {
20214     TraceMethodEnter(self);
20215 
20216     return Certificate_new_from_CERTCertificate(self->node.cert, true);
20217 }
20218 
20219 static PyObject *
CertVerifyLogNode_get_error(CertVerifyLogNode * self,void * closure)20220 CertVerifyLogNode_get_error(CertVerifyLogNode *self, void *closure)
20221 {
20222     TraceMethodEnter(self);
20223 
20224     return PyLong_FromLong(self->node.error);
20225 }
20226 
20227 static PyObject *
CertVerifyLogNode_get_depth(CertVerifyLogNode * self,void * closure)20228 CertVerifyLogNode_get_depth(CertVerifyLogNode *self, void *closure)
20229 {
20230     TraceMethodEnter(self);
20231 
20232     return PyLong_FromLong(self->node.depth);
20233 }
20234 
20235 static
20236 PyGetSetDef CertVerifyLogNode_getseters[] = {
20237     {"certificate", (getter)CertVerifyLogNode_get_certificate, NULL,
20238      "returns the certificate as a `Certificate` object", NULL},
20239     {"error", (getter)CertVerifyLogNode_get_error, NULL,
20240      "returns the error code as an integer", NULL},
20241     {"depth", (getter)CertVerifyLogNode_get_depth, NULL,
20242      "returns the chain position as an integer", NULL},
20243     {NULL}  /* Sentinel */
20244 };
20245 
20246 static PyMemberDef CertVerifyLogNode_members[] = {
20247     {NULL}  /* Sentinel */
20248 };
20249 
20250 /* ============================== Class Methods ============================= */
20251 
20252 static PyObject *
CertVerifyLogNodeError_format_lines(CertVerifyLogNode * self,int level,PyObject * lines)20253 CertVerifyLogNodeError_format_lines(CertVerifyLogNode *self, int level, PyObject *lines)
20254 {
20255     RepresentationKind repr_kind = AsEnumName;
20256     PyObject *obj = NULL;
20257     PyObject *py_cert = NULL;
20258     NSPRErrorDesc const *error_desc = NULL;
20259     CERTVerifyLogNode *node = NULL;
20260 
20261     if (!lines) {
20262         goto fail;
20263     }
20264 
20265     node = &self->node;
20266 
20267     if ((error_desc = lookup_nspr_error(node->error)) == NULL) {
20268         if ((obj = PyUnicode_FromFormat(_("Unknown error code %ld (%#lx)"),
20269                                         node->error, node->error)) == NULL) {
20270             goto fail;
20271         }
20272     } else {
20273         if ((obj = PyUnicode_FromFormat("[%s] %s",
20274                                         error_desc->name,
20275                                         error_desc->string)) == NULL) {
20276             goto fail;
20277         }
20278     }
20279     FMT_OBJ_AND_APPEND(lines, _("Error"), obj, level, fail);
20280     Py_CLEAR(obj);
20281 
20282     switch (node->error) {
20283     case SEC_ERROR_INADEQUATE_KEY_USAGE: {
20284         // NSS WART - pointers and ints are not the same thing
20285 #pragma GCC diagnostic push
20286 #pragma GCC diagnostic ignored "-Wpointer-to-int-cast"
20287         unsigned int flags = (unsigned int)node->arg;
20288 #pragma GCC diagnostic pop
20289 
20290         if ((obj = key_usage_flags(flags, repr_kind)) == NULL) {
20291             goto fail;
20292         }
20293         FMT_OBJ_AND_APPEND(lines, _("Inadequate Key Usage"), obj, level, fail);
20294         Py_CLEAR(obj);
20295     } break;
20296     case SEC_ERROR_INADEQUATE_CERT_TYPE: {
20297         // NSS WART - pointers and ints are not the same thing
20298 #pragma GCC diagnostic push
20299 #pragma GCC diagnostic ignored "-Wpointer-to-int-cast"
20300         unsigned int flags = (unsigned int)node->arg;
20301 #pragma GCC diagnostic pop
20302 
20303         if ((obj = cert_type_flags(flags, repr_kind)) == NULL) {
20304             goto fail;
20305         }
20306         FMT_OBJ_AND_APPEND(lines, _("Inadequate Cert Type"), obj, level, fail);
20307         Py_CLEAR(obj);
20308     } break;
20309     case SEC_ERROR_UNKNOWN_ISSUER:
20310     case SEC_ERROR_UNTRUSTED_ISSUER:
20311     case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
20312         if ((py_cert = Certificate_new_from_CERTCertificate(node->cert, true)) == NULL) {
20313             goto fail;
20314         }
20315         if ((obj = Certificate_get_issuer((Certificate *)py_cert, NULL)) == NULL) {
20316             goto fail;
20317         }
20318         Py_CLEAR(py_cert);
20319 
20320         FMT_OBJ_AND_APPEND(lines, _("Issuer"), obj, level, fail);
20321         Py_CLEAR(obj);
20322         break;
20323     default:
20324         break;
20325     }
20326 
20327     return lines;
20328  fail:
20329     Py_XDECREF(py_cert);
20330     Py_XDECREF(obj);
20331     return NULL;
20332 }
20333 
20334 static PyObject *
CertVerifyLogNode_format_lines(CertVerifyLogNode * self,PyObject * args,PyObject * kwds)20335 CertVerifyLogNode_format_lines(CertVerifyLogNode *self, PyObject *args, PyObject *kwds)
20336 {
20337     static char *kwlist[] = {"level", NULL};
20338     int level = 0;
20339     PyObject *lines = NULL;
20340     PyObject *obj = NULL;
20341     Certificate *py_cert = NULL;
20342     CERTVerifyLogNode *node = NULL;
20343 
20344     TraceMethodEnter(self);
20345 
20346     node = &self->node;
20347 
20348     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:format_lines", kwlist, &level))
20349         return NULL;
20350 
20351     if ((lines = PyList_New(0)) == NULL) {
20352         return NULL;
20353     }
20354 
20355     FMT_LABEL_AND_APPEND(lines, _("Certificate"), level, fail);
20356 
20357     if ((py_cert = (Certificate *)Certificate_new_from_CERTCertificate(node->cert, true)) == NULL) {
20358         goto fail;
20359     }
20360 
20361     if (Certificate_summary_format_lines(py_cert, level+1, lines) == NULL) {
20362         goto fail;
20363     }
20364     Py_CLEAR(py_cert);
20365 
20366     if ((obj = PyLong_FromLong(node->depth)) == NULL){
20367         goto fail;
20368     }
20369     FMT_OBJ_AND_APPEND(lines, _("Depth"), obj, level, fail);
20370     Py_CLEAR(obj);
20371 
20372     if (CertVerifyLogNodeError_format_lines(self, level, lines) == NULL) {
20373         goto fail;
20374     }
20375 
20376     return lines;
20377  fail:
20378     Py_XDECREF(py_cert);
20379     Py_XDECREF(obj);
20380     Py_XDECREF(lines);
20381     return NULL;
20382 }
20383 
20384 static PyObject *
CertVerifyLogNode_format(CertVerifyLogNode * self,PyObject * args,PyObject * kwds)20385 CertVerifyLogNode_format(CertVerifyLogNode *self, PyObject *args, PyObject *kwds)
20386 {
20387     TraceMethodEnter(self);
20388 
20389     return format_from_lines((format_lines_func)CertVerifyLogNode_format_lines, (PyObject *)self, args, kwds);
20390 }
20391 
20392 static PyObject *
CertVerifyLogNode_str(CertVerifyLogNode * self)20393 CertVerifyLogNode_str(CertVerifyLogNode *self)
20394 {
20395     PyObject *py_formatted_result = NULL;
20396 
20397     TraceMethodEnter(self);
20398 
20399     py_formatted_result =  CertVerifyLogNode_format(self, empty_tuple, NULL);
20400     return py_formatted_result;
20401 
20402 }
20403 
20404 
20405 static PyMethodDef CertVerifyLogNode_methods[] = {
20406     {"format_lines", (PyCFunction)CertVerifyLogNode_format_lines,   METH_VARARGS|METH_KEYWORDS, generic_format_lines_doc},
20407     {"format",       (PyCFunction)CertVerifyLogNode_format,         METH_VARARGS|METH_KEYWORDS, generic_format_doc},
20408     {NULL, NULL}  /* Sentinel */
20409 };
20410 
20411 /* =========================== Class Construction =========================== */
20412 
20413 static PyObject *
CertVerifyLogNode_new(PyTypeObject * type,PyObject * args,PyObject * kwds)20414 CertVerifyLogNode_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
20415 {
20416     CertVerifyLogNode *self;
20417 
20418     TraceObjNewEnter(type);
20419 
20420     if ((self = (CertVerifyLogNode *)type->tp_alloc(type, 0)) == NULL) {
20421         return NULL;
20422     }
20423 
20424     memset(&self->node, 0, sizeof(self->node));
20425 
20426     TraceObjNewLeave(self);
20427     return (PyObject *)self;
20428 }
20429 
20430 static void
CertVerifyLogNode_dealloc(CertVerifyLogNode * self)20431 CertVerifyLogNode_dealloc(CertVerifyLogNode* self)
20432 {
20433     TraceMethodEnter(self);
20434 
20435     if (self->node.cert) {
20436         CERT_DestroyCertificate(self->node.cert);
20437     }
20438 
20439     Py_TYPE(self)->tp_free((PyObject*)self);
20440 }
20441 
20442 PyDoc_STRVAR(CertVerifyLogNode_doc,
20443 "CertVerifyLogNode()\n\
20444 \n\
20445 An object detailing specific diagnostic information concerning\n\
20446 a single failure during certification validation.\n\
20447 These are collected in a `CertVerifyLog` object.\n\
20448 ");
20449 
20450 static PyTypeObject CertVerifyLogNodeType = {
20451     PyVarObject_HEAD_INIT(NULL, 0)
20452     "nss.nss.CertVerifyLogNode",		/* tp_name */
20453     sizeof(CertVerifyLogNode),			/* tp_basicsize */
20454     0,						/* tp_itemsize */
20455     (destructor)CertVerifyLogNode_dealloc,	/* tp_dealloc */
20456     0,						/* tp_print */
20457     0,						/* tp_getattr */
20458     0,						/* tp_setattr */
20459     0,						/* tp_compare */
20460     0,						/* tp_repr */
20461     0,						/* tp_as_number */
20462     0,						/* tp_as_sequence */
20463     0,						/* tp_as_mapping */
20464     0,						/* tp_hash */
20465     0,						/* tp_call */
20466     (reprfunc)CertVerifyLogNode_str,		/* tp_str */
20467     0,						/* tp_getattro */
20468     0,						/* tp_setattro */
20469     0,						/* tp_as_buffer */
20470     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,	/* tp_flags */
20471     CertVerifyLogNode_doc,			/* tp_doc */
20472     (traverseproc)0,				/* tp_traverse */
20473     (inquiry)0,					/* tp_clear */
20474     0,						/* tp_richcompare */
20475     0,						/* tp_weaklistoffset */
20476     0,						/* tp_iter */
20477     0,						/* tp_iternext */
20478     CertVerifyLogNode_methods,			/* tp_methods */
20479     CertVerifyLogNode_members,			/* tp_members */
20480     CertVerifyLogNode_getseters,		/* tp_getset */
20481     0,						/* tp_base */
20482     0,						/* tp_dict */
20483     0,						/* tp_descr_get */
20484     0,						/* tp_descr_set */
20485     0,						/* tp_dictoffset */
20486     0,						/* tp_init */
20487     0,						/* tp_alloc */
20488     CertVerifyLogNode_new,			/* tp_new */
20489 };
20490 
20491 static PyObject *
CertVerifyLogNode_new_from_CERTVerifyLogNode(CERTVerifyLogNode * node)20492 CertVerifyLogNode_new_from_CERTVerifyLogNode(CERTVerifyLogNode *node)
20493 {
20494     CertVerifyLogNode *self = NULL;
20495 
20496     TraceObjNewEnter(NULL);
20497 
20498     if ((self = (CertVerifyLogNode *) CertVerifyLogNodeType.tp_new(&CertVerifyLogNodeType, NULL, NULL)) == NULL) {
20499         return NULL;
20500     }
20501 
20502     self->node.cert  = CERT_DupCertificate(node->cert);
20503     self->node.error = node->error;
20504     self->node.depth = node->depth;
20505     self->node.arg   = node->arg;
20506     self->node.next  = NULL;
20507     self->node.prev  = NULL;
20508 
20509     TraceObjNewLeave(self);
20510 
20511     return (PyObject *) self;
20512 }
20513 /* ========================================================================== */
20514 /* ========================== CertVerifyLog Class =========================== */
20515 /* ========================================================================== */
20516 
20517 /* ============================ Attribute Access ============================ */
20518 
20519 static PyObject *
CertVerifyLog_get_count(CertVerifyLog * self,void * closure)20520 CertVerifyLog_get_count(CertVerifyLog *self, void *closure)
20521 {
20522     TraceMethodEnter(self);
20523 
20524     return PyLong_FromLong(self->log.count);
20525 }
20526 
20527 static
20528 PyGetSetDef CertVerifyLog_getseters[] = {
20529     {"count", (getter)CertVerifyLog_get_count,    NULL,
20530      "number of validation errors", NULL},
20531     {NULL}  /* Sentinel */
20532 };
20533 
20534 static PyMemberDef CertVerifyLog_members[] = {
20535     {NULL}  /* Sentinel */
20536 };
20537 
20538 /* ============================== Class Methods ============================= */
20539 
20540 static PyObject *
CertVerifyLog_format_lines(CertVerifyLog * self,PyObject * args,PyObject * kwds)20541 CertVerifyLog_format_lines(CertVerifyLog *self, PyObject *args, PyObject *kwds)
20542 {
20543     static char *kwlist[] = {"level", NULL};
20544     int level = 0;
20545     PyObject *lines = NULL;
20546     PyObject *obj = NULL;
20547     Py_ssize_t i, n_items;
20548     unsigned int depth = ~0;
20549     CertVerifyLogNode *py_node = NULL;
20550     Certificate *py_cert = NULL;
20551 
20552     TraceMethodEnter(self);
20553 
20554     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:format_lines", kwlist, &level))
20555         return NULL;
20556 
20557     if ((lines = PyList_New(0)) == NULL) {
20558         return NULL;
20559     }
20560 
20561     if ((obj = PyLong_FromLong(self->log.count)) == NULL) {
20562         goto fail;
20563     }
20564     FMT_OBJ_AND_APPEND(lines, _("Validation Errors"), obj, level, fail);
20565     Py_CLEAR(obj);
20566 
20567 
20568     n_items = CertVerifyLog_length(self);
20569 
20570     for (i = 0; i < n_items; i++) {
20571         CERTVerifyLogNode *node = NULL;
20572 
20573         py_node = (CertVerifyLogNode *)CertVerifyLog_item(self, i);
20574         node = &py_node->node;
20575 
20576         if (depth != node->depth) {
20577             depth = node->depth;
20578 
20579             if ((obj = PyBytes_FromFormat(_("Certificate at chain depth %u"), node->depth)) == NULL) {
20580                 goto fail;
20581             }
20582             FMT_LABEL_AND_APPEND(lines, PyBytes_AsString(obj), level, fail);
20583             Py_CLEAR(obj);
20584 
20585             if ((py_cert = (Certificate *)Certificate_new_from_CERTCertificate(node->cert, true)) == NULL) {
20586                 goto fail;
20587             }
20588 
20589             if (Certificate_summary_format_lines(py_cert, level+1, lines) == NULL) {
20590                 goto fail;
20591             }
20592 
20593             Py_CLEAR(py_cert);
20594 
20595             /* Add blank line between cert and errors */
20596             FMT_LABEL_AND_APPEND(lines, NULL, level, fail);
20597         }
20598 
20599         if ((obj = PyBytes_FromFormat(_("Validation Error #%zd"), i+1)) == NULL) {
20600             goto fail;
20601         }
20602         FMT_LABEL_AND_APPEND(lines, PyBytes_AsString(obj), level+1, fail);
20603         Py_CLEAR(obj);
20604 
20605         if (CertVerifyLogNodeError_format_lines(py_node, level+2, lines) == NULL) {
20606             goto fail;
20607         }
20608 
20609         Py_CLEAR(py_node);
20610 
20611         //if (i < n_items-1) {    /* blank separator line */
20612         //    FMT_LABEL_AND_APPEND(lines, NULL, level, fail);
20613         //}
20614 
20615     }
20616 
20617     return lines;
20618  fail:
20619     Py_XDECREF(py_node);
20620     Py_XDECREF(py_cert);
20621     Py_XDECREF(obj);
20622     Py_XDECREF(lines);
20623     return NULL;
20624 }
20625 
20626 static PyObject *
CertVerifyLog_format(CertVerifyLog * self,PyObject * args,PyObject * kwds)20627 CertVerifyLog_format(CertVerifyLog *self, PyObject *args, PyObject *kwds)
20628 {
20629     TraceMethodEnter(self);
20630 
20631     return format_from_lines((format_lines_func)CertVerifyLog_format_lines, (PyObject *)self, args, kwds);
20632 }
20633 
20634 static PyObject *
CertVerifyLog_str(CertVerifyLog * self)20635 CertVerifyLog_str(CertVerifyLog *self)
20636 {
20637     PyObject *py_formatted_result = NULL;
20638 
20639     TraceMethodEnter(self);
20640 
20641     py_formatted_result =  CertVerifyLog_format(self, empty_tuple, NULL);
20642     return py_formatted_result;
20643 
20644 }
20645 
20646 static PyMethodDef CertVerifyLog_methods[] = {
20647     {"format_lines", (PyCFunction)CertVerifyLog_format_lines,   METH_VARARGS|METH_KEYWORDS, generic_format_lines_doc},
20648     {"format",       (PyCFunction)CertVerifyLog_format,         METH_VARARGS|METH_KEYWORDS, generic_format_doc},
20649     {NULL, NULL}  /* Sentinel */
20650 };
20651 
20652 /* =========================== Sequence Protocol ============================ */
20653 static Py_ssize_t
CertVerifyLog_length(CertVerifyLog * self)20654 CertVerifyLog_length(CertVerifyLog *self)
20655 {
20656     return self->log.count;
20657 }
20658 
20659 static PyObject *
CertVerifyLog_item(CertVerifyLog * self,register Py_ssize_t i)20660 CertVerifyLog_item(CertVerifyLog *self, register Py_ssize_t i)
20661 {
20662     CERTVerifyLogNode *node = NULL;
20663     Py_ssize_t index;
20664 
20665     for (node = self->log.head, index = 0;
20666          node && index <= i;
20667          node = node->next, index++) {
20668         if (i == index) {
20669             return CertVerifyLogNode_new_from_CERTVerifyLogNode(node);
20670         }
20671     }
20672 
20673     PyErr_SetString(PyExc_IndexError, "CertVerifyLog index out of range");
20674     return NULL;
20675 }
20676 
20677 
20678 /* =========================== Class Construction =========================== */
20679 
20680 static PyObject *
CertVerifyLog_new(PyTypeObject * type,PyObject * args,PyObject * kwds)20681 CertVerifyLog_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
20682 {
20683     CertVerifyLog *self;
20684 
20685     TraceObjNewEnter(type);
20686 
20687     if ((self = (CertVerifyLog *)type->tp_alloc(type, 0)) == NULL) {
20688         return NULL;
20689     }
20690 
20691     if ((self->log.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE)) == NULL) {
20692         type->tp_free(self);
20693         return set_nspr_error(NULL);
20694     }
20695 
20696     self->log.count = 0;
20697     self->log.head = NULL;
20698     self->log.tail = NULL;
20699 
20700     TraceObjNewLeave(self);
20701     return (PyObject *)self;
20702 }
20703 
20704 static void
CertVerifyLog_dealloc(CertVerifyLog * self)20705 CertVerifyLog_dealloc(CertVerifyLog* self)
20706 {
20707     CERTVerifyLogNode *node = NULL;
20708 
20709     TraceMethodEnter(self);
20710 
20711     for (node = self->log.head; node; node = node->next) {
20712         if (node->cert) {
20713             CERT_DestroyCertificate(node->cert);
20714         }
20715     }
20716     PORT_FreeArena(self->log.arena, PR_FALSE);
20717 
20718     Py_TYPE(self)->tp_free((PyObject*)self);
20719 }
20720 
20721 PyDoc_STRVAR(CertVerifyLog_doc,
20722 "CertVerifyLog()\n\
20723 \n\
20724 An object which collects diagnostic information during\n\
20725 certification validation.\n\
20726 ");
20727 
20728 static PySequenceMethods CertVerifyLog_as_sequence = {
20729     (lenfunc)CertVerifyLog_length,		/* sq_length */
20730     0,						/* sq_concat */
20731     0,						/* sq_repeat */
20732     (ssizeargfunc)CertVerifyLog_item,		/* sq_item */
20733     0,						/* sq_slice */
20734     0,						/* sq_ass_item */
20735     0,						/* sq_ass_slice */
20736     0,						/* sq_contains */
20737     0,						/* sq_inplace_concat */
20738     0,						/* sq_inplace_repeat */
20739 };
20740 
20741 static PyTypeObject CertVerifyLogType = {
20742     PyVarObject_HEAD_INIT(NULL, 0)
20743     "nss.nss.CertVerifyLog",			/* tp_name */
20744     sizeof(CertVerifyLog),			/* tp_basicsize */
20745     0,						/* tp_itemsize */
20746     (destructor)CertVerifyLog_dealloc,		/* tp_dealloc */
20747     0,						/* tp_print */
20748     0,						/* tp_getattr */
20749     0,						/* tp_setattr */
20750     0,						/* tp_compare */
20751     0,						/* tp_repr */
20752     0,						/* tp_as_number */
20753     &CertVerifyLog_as_sequence,			/* tp_as_sequence */
20754     0,						/* tp_as_mapping */
20755     0,						/* tp_hash */
20756     0,						/* tp_call */
20757     (reprfunc)CertVerifyLog_str,		/* tp_str */
20758     0,						/* tp_getattro */
20759     0,						/* tp_setattro */
20760     0,						/* tp_as_buffer */
20761     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,	/* tp_flags */
20762     CertVerifyLog_doc,				/* tp_doc */
20763     (traverseproc)0,				/* tp_traverse */
20764     (inquiry)0,					/* tp_clear */
20765     0,						/* tp_richcompare */
20766     0,						/* tp_weaklistoffset */
20767     0,						/* tp_iter */
20768     0,						/* tp_iternext */
20769     CertVerifyLog_methods,			/* tp_methods */
20770     CertVerifyLog_members,			/* tp_members */
20771     CertVerifyLog_getseters,			/* tp_getset */
20772     0,						/* tp_base */
20773     0,						/* tp_dict */
20774     0,						/* tp_descr_get */
20775     0,						/* tp_descr_set */
20776     0,						/* tp_dictoffset */
20777     0,						/* tp_init */
20778     0,						/* tp_alloc */
20779     CertVerifyLog_new,				/* tp_new */
20780 };
20781 /* ========================== PK11 Methods =========================== */
20782 
20783 static char *
PK11_password_callback(PK11SlotInfo * slot,PRBool retry,void * arg)20784 PK11_password_callback(PK11SlotInfo *slot, PRBool retry, void *arg)
20785 {
20786     PyGILState_STATE gstate;
20787     Py_ssize_t n_base_args = 2;
20788     PyObject *password_callback = NULL;
20789     PyObject *pin_args = arg; /* borrowed reference, don't decrement */
20790     PyObject *py_slot = NULL;
20791     PyObject *item;
20792     PyObject *result = NULL;
20793     PyObject *new_args = NULL;
20794     Py_ssize_t argc;
20795     int i, j;
20796     char *password = NULL;
20797 
20798     gstate = PyGILState_Ensure();
20799 
20800     TraceMessage("PK11_password_callback: enter");
20801 
20802     if ((password_callback = get_thread_local("password_callback")) == NULL) {
20803         if (!PyErr_Occurred()) {
20804             PySys_WriteStderr("PK11 password callback undefined\n");
20805         } else {
20806             PyErr_Print();
20807         }
20808 	PyGILState_Release(gstate);
20809         return NULL;
20810     }
20811 
20812     argc = n_base_args;
20813     if (pin_args) {
20814         if (PyTuple_Check(pin_args)) {
20815             argc += PyTuple_Size(pin_args);
20816         } else {
20817             PySys_WriteStderr("Error, PK11 password callback expected args to be tuple\n");
20818             PyErr_Print();
20819         }
20820     }
20821 
20822     if ((new_args = PyTuple_New(argc)) == NULL) {
20823         PySys_WriteStderr("PK11 password callback: out of memory\n");
20824         goto exit;
20825     }
20826 
20827     if ((py_slot = PK11Slot_new_from_PK11SlotInfo(slot)) == NULL) {
20828         PySys_WriteStderr("exception in PK11 password callback\n");
20829         PyErr_Print();
20830         goto exit;
20831     }
20832     /*
20833      * Every NSS function that returns a slot has it's reference count
20834      * incremented. We wrap that slot in a PK11Slot Python object and
20835      * when the PK11Slot Python object is deallocated we decrement the
20836      * NSS slot reference count by calling PK11_FreeSlot.
20837      *
20838      * However in this callback we're not returned a slot, rather we
20839      * are passed a slot, it's reference count has not been
20840      * incremented. But we still wrap the NSS slot with a PK11Slot
20841      * Python object which when deallocated will decrement the NSS
20842      * slot reference count. Therefore we increment the NSS slots
20843      * reference count by calling PK11_ReferenceSlot.
20844      */
20845     PK11_ReferenceSlot(((PK11Slot *)py_slot)->slot);
20846 
20847     PyTuple_SetItem(new_args, 0, py_slot);
20848     PyTuple_SetItem(new_args, 1, PyBool_FromLong(retry));
20849 
20850     for (i = n_base_args, j = 0; i < argc; i++, j++) {
20851         item = PyTuple_GetItem(pin_args, j);
20852         Py_INCREF(item);
20853         PyTuple_SetItem(new_args, i, item);
20854     }
20855 
20856     if ((result = PyObject_CallObject(password_callback, new_args)) == NULL) {
20857         PySys_WriteStderr("exception in PK11 password callback\n");
20858         PyErr_Print();  /* this also clears the error */
20859         goto exit;
20860     }
20861 
20862     if (PyBaseString_Check(result)) {
20863         PyObject *py_password = NULL;
20864 
20865         if ((py_password = PyBaseString_UTF8(result, "PK11 password callback result")) != NULL) {
20866             password = PORT_Strdup(PyBytes_AsString(py_password));
20867             Py_DECREF(py_password);
20868         } else {
20869             goto exit;
20870         }
20871     } else if (PyNone_Check(result)) {
20872         password = NULL;
20873     } else {
20874         PySys_WriteStderr("Error, PK11 password callback expected string result or None.\n");
20875         goto exit;
20876     }
20877 
20878  exit:
20879     TraceMessage("PK11_password_callback: exiting");
20880 
20881     Py_XDECREF(new_args);
20882     Py_XDECREF(result);
20883 
20884     PyGILState_Release(gstate);
20885 
20886     return password;
20887 }
20888 
20889 /* ========================================================================== */
20890 /* ========================= Global PK11 Functions ========================== */
20891 /* ========================================================================== */
20892 
20893 PyDoc_STRVAR(pk11_set_password_callback_doc,
20894 "set_password_callback(callback)\n\
20895 \n\
20896 :Parameters:\n\
20897     callback : function pointer\n\
20898         The callback function\n\
20899         \n\
20900 \n\
20901 Defines a callback function used by the NSS libraries whenever\n\
20902 information protected by a password needs to be retrieved from the key\n\
20903 or certificate databases.\n\
20904 \n\
20905 Many tokens keep track of the number of attempts to enter a password\n\
20906 and do not allow further attempts after a certain point. Therefore, if\n\
20907 the retry argument is True, indicating that the password was tried and\n\
20908 is wrong, the callback function should return None to indicate that it\n\
20909 is unsuccessful, rather than attempting to return the same password\n\
20910 again. Failing to terminate when the retry argument is True can result\n\
20911 in an endless loop. The user_dataN arguments can also be used to keep\n\
20912 track of the number of times the callback has been invoked.\n\
20913 \n\
20914 Several functions in the NSS libraries use the password callback\n\
20915 function to obtain the password before performing operations that\n\
20916 involve the protected information.  The extra user_dataN parameters to\n\
20917 the password callback function is application-defined and can be used\n\
20918 for any purpose. When NSS libraries call the password callback\n\
20919 function the value they pass for the user_dataN arguments is\n\
20920 determined by `ssl.SSLSocket.set_pkcs11_pin_arg()`.\n\
20921 \n\
20922 The callback has the signature::\n\
20923     \n\
20924     password_callback(slot, retry, [user_data1, ...]) -> string or None\n\
20925 \n\
20926 slot\n\
20927     PK11Slot object\n\
20928 retry\n\
20929     boolean indicating if this is a retry. This implies that the\n\
20930     callback has previously returned the wrong password.\n\
20931 user_dataN\n\
20932     zero or more caller supplied optional parameters\n\
20933 \n\
20934 The callback should return a string or None to indicate a valid\n\
20935 password cannot be supplied. Returning None will prevent the callback\n\
20936 from being invoked again.\n\
20937 ");
20938 
20939 static PyObject *
pk11_set_password_callback(PyObject * self,PyObject * args)20940 pk11_set_password_callback(PyObject *self, PyObject *args)
20941 {
20942     PyObject *callback = NULL;
20943 
20944     TraceMethodEnter(self);
20945 
20946     if (!PyArg_ParseTuple(args, "O:set_password_callback", &callback)) {
20947         return NULL;
20948     }
20949 
20950     if (!PyCallable_Check(callback)) {
20951         PyErr_SetString(PyExc_TypeError, "callback must be callable");
20952         return NULL;
20953     }
20954 
20955     if (set_thread_local("password_callback", callback) < 0) {
20956         return NULL;
20957     }
20958 
20959     PK11_SetPasswordFunc(PK11_password_callback);
20960 
20961     Py_RETURN_NONE;
20962 }
20963 
20964 PyDoc_STRVAR(pk11_list_certs_doc,
20965 "list_certs(type, [user_data1, ...]) -> (`Certificate`, ...)\n\
20966 \n\
20967 :Parameters:\n\
20968     type : int\n\
20969         PK11CertList* enumerated constant.\n\
20970     user_dataN : object ...\n\
20971         zero or more caller supplied parameters which will\n\
20972         be passed to the password callback function\n\
20973 \n\
20974 Given the type of certificates to list return a tuple of `Certificate`\n\
20975 objects matching that type.\n\
20976 ");
20977 
20978 static PyObject *
pk11_list_certs(PyObject * self,PyObject * args)20979 pk11_list_certs(PyObject *self, PyObject *args)
20980 {
20981     Py_ssize_t n_base_args = 1;
20982     Py_ssize_t argc;
20983     PyObject *parse_args = NULL;
20984     PyObject *pin_args = NULL;
20985     int type = PK11CertListAll;
20986     CERTCertList *cert_list = NULL;
20987     PyObject *tuple = NULL;
20988 
20989     TraceMethodEnter(self);
20990 
20991     argc = PyTuple_Size(args);
20992     if (argc == n_base_args) {
20993         Py_INCREF(args);
20994         parse_args = args;
20995     } else {
20996         parse_args = PyTuple_GetSlice(args, 0, n_base_args);
20997     }
20998     if (!PyArg_ParseTuple(parse_args, "i:list_certs", &type)) {
20999         Py_DECREF(parse_args);
21000         return NULL;
21001     }
21002     Py_DECREF(parse_args);
21003 
21004     pin_args = PyTuple_GetSlice(args, n_base_args, argc);
21005 
21006     Py_BEGIN_ALLOW_THREADS
21007     if ((cert_list = PK11_ListCerts(type, pin_args)) == NULL) {
21008 	Py_BLOCK_THREADS
21009         Py_DECREF(pin_args);
21010         return set_nspr_error(NULL);
21011     }
21012     Py_END_ALLOW_THREADS
21013 
21014     Py_DECREF(pin_args);
21015 
21016     tuple = CERTCertList_to_tuple(cert_list, true);
21017     CERT_DestroyCertList(cert_list);
21018     return tuple;
21019 }
21020 
21021 PyDoc_STRVAR(pk11_find_certs_from_email_addr_doc,
21022 "find_certs_from_email_addr(email, [user_data1, ...]) -> (`Certificate`, ...)\n\
21023 \n\
21024 :Parameters:\n\
21025     email : string\n\
21026         email address.\n\
21027     user_dataN : object ...\n\
21028         zero or more caller supplied parameters which will\n\
21029         be passed to the password callback function\n\
21030 \n\
21031 Given an email address return a tuple of `Certificate`\n\
21032 objects containing that address.\n\
21033 ");
21034 
21035 static PyObject *
pk11_find_certs_from_email_addr(PyObject * self,PyObject * args)21036 pk11_find_certs_from_email_addr(PyObject *self, PyObject *args)
21037 {
21038     Py_ssize_t n_base_args = 1;
21039     Py_ssize_t argc;
21040     PyObject *parse_args = NULL;
21041     PyObject *pin_args = NULL;
21042     char *email_addr = NULL;
21043     CERTCertList *cert_list = NULL;
21044     PyObject *tuple = NULL;
21045 
21046     TraceMethodEnter(self);
21047 
21048     argc = PyTuple_Size(args);
21049     if (argc == n_base_args) {
21050         Py_INCREF(args);
21051         parse_args = args;
21052     } else {
21053         parse_args = PyTuple_GetSlice(args, 0, n_base_args);
21054     }
21055     if (!PyArg_ParseTuple(parse_args, "s:find_certs_from_email_addr",
21056                           &email_addr)) {
21057         Py_DECREF(parse_args);
21058         return NULL;
21059     }
21060     Py_DECREF(parse_args);
21061 
21062     pin_args = PyTuple_GetSlice(args, n_base_args, argc);
21063 
21064     Py_BEGIN_ALLOW_THREADS
21065     if ((cert_list = PK11_FindCertsFromEmailAddress(email_addr, pin_args)) == NULL) {
21066 	Py_BLOCK_THREADS
21067         Py_DECREF(pin_args);
21068         return set_nspr_error(NULL);
21069     }
21070     Py_END_ALLOW_THREADS
21071 
21072     Py_DECREF(pin_args);
21073 
21074     tuple = CERTCertList_to_tuple(cert_list, true);
21075     CERT_DestroyCertList(cert_list);
21076     return tuple;
21077 }
21078 
21079 PyDoc_STRVAR(pk11_find_certs_from_nickname_doc,
21080 "find_certs_from_nickname(email, [user_data1, ...]) -> (`Certificate`, ...)\n\
21081 \n\
21082 :Parameters:\n\
21083     nickname : string\n\
21084         certificate nickname.\n\
21085     user_dataN : object ...\n\
21086         zero or more caller supplied parameters which will\n\
21087         be passed to the password callback function\n\
21088 \n\
21089 Given a certificate nickname return a tuple of `Certificate`\n\
21090 objects matching that nickname.\n\
21091 ");
21092 
21093 static PyObject *
pk11_find_certs_from_nickname(PyObject * self,PyObject * args)21094 pk11_find_certs_from_nickname(PyObject *self, PyObject *args)
21095 {
21096     Py_ssize_t n_base_args = 1;
21097     Py_ssize_t argc;
21098     PyObject *parse_args = NULL;
21099     PyObject *pin_args = NULL;
21100     char *nickname = NULL;
21101     CERTCertList *cert_list = NULL;
21102     PyObject *tuple = NULL;
21103 
21104     TraceMethodEnter(self);
21105 
21106     argc = PyTuple_Size(args);
21107     if (argc == n_base_args) {
21108         Py_INCREF(args);
21109         parse_args = args;
21110     } else {
21111         parse_args = PyTuple_GetSlice(args, 0, n_base_args);
21112     }
21113     if (!PyArg_ParseTuple(parse_args, "s:find_certs_from_nickname",
21114                           &nickname)) {
21115         Py_DECREF(parse_args);
21116         return NULL;
21117     }
21118     Py_DECREF(parse_args);
21119 
21120     pin_args = PyTuple_GetSlice(args, n_base_args, argc);
21121 
21122     Py_BEGIN_ALLOW_THREADS
21123     if ((cert_list = PK11_FindCertsFromNickname(nickname, pin_args)) == NULL) {
21124 	Py_BLOCK_THREADS
21125         Py_DECREF(pin_args);
21126         return set_nspr_error(NULL);
21127     }
21128     Py_END_ALLOW_THREADS
21129 
21130     Py_DECREF(pin_args);
21131 
21132     tuple = CERTCertList_to_tuple(cert_list, true);
21133     CERT_DestroyCertList(cert_list);
21134     return tuple;
21135 }
21136 
21137 PyDoc_STRVAR(pk11_find_cert_from_nickname_doc,
21138 "find_cert_from_nickname(nickname, [user_data1, ...]) -> Certificate\n\
21139 \n\
21140 :Parameters:\n\
21141     nickname : string\n\
21142         certificate nickname to search for\n\
21143     user_dataN : object ...\n\
21144         zero or more caller supplied parameters which will\n\
21145         be passed to the password callback function\n\
21146 \n\
21147 A nickname is an alias for a certificate subject. There may be\n\
21148 multiple certificates with the same subject, and hence the same\n\
21149 nickname. This function will return the newest certificate that\n\
21150 matches the subject, based on the NotBefore / NotAfter fields of the\n\
21151 certificate.\n\
21152 ");
21153 
21154 static PyObject *
pk11_find_cert_from_nickname(PyObject * self,PyObject * args)21155 pk11_find_cert_from_nickname(PyObject *self, PyObject *args)
21156 {
21157     Py_ssize_t n_base_args = 1;
21158     Py_ssize_t argc;
21159     PyObject *parse_args = NULL;
21160     PyObject *pin_args = NULL;
21161     char *nickname = NULL;
21162     CERTCertificate *cert = NULL;
21163     PyObject *py_cert = NULL;
21164 
21165     TraceMethodEnter(self);
21166 
21167     argc = PyTuple_Size(args);
21168     if (argc == n_base_args) {
21169         Py_INCREF(args);
21170         parse_args = args;
21171     } else {
21172         parse_args = PyTuple_GetSlice(args, 0, n_base_args);
21173     }
21174     if (!PyArg_ParseTuple(parse_args, "s:find_cert_from_nickname", &nickname)) {
21175         Py_DECREF(parse_args);
21176         return NULL;
21177     }
21178     Py_DECREF(parse_args);
21179 
21180     pin_args = PyTuple_GetSlice(args, n_base_args, argc);
21181 
21182     Py_BEGIN_ALLOW_THREADS
21183     if ((cert = PK11_FindCertFromNickname(nickname, pin_args)) == NULL) {
21184 	Py_BLOCK_THREADS
21185         Py_DECREF(pin_args);
21186         return set_nspr_error(NULL);
21187     }
21188     Py_END_ALLOW_THREADS
21189 
21190     Py_DECREF(pin_args);
21191 
21192     if ((py_cert = Certificate_new_from_CERTCertificate(cert, false)) == NULL) {
21193         return NULL;
21194     }
21195 
21196     return py_cert;
21197 }
21198 
21199 PyDoc_STRVAR(pk11_find_key_by_any_cert_doc,
21200 "find_key_by_any_cert(cert, [user_data1, ...]) -> Certificate\n\
21201 \n\
21202 :Parameters:\n\
21203     cert : Certificate object\n\
21204         certificate whose private key is being searched for\n\
21205     user_dataN : object ...\n\
21206         zero or more caller supplied parameters which will\n\
21207         be passed to the password callback function\n\
21208 \n\
21209 Finds the private key associated with a specified certificate in any\n\
21210 available slot.\n\
21211 ");
21212 
21213 static PyObject *
pk11_find_key_by_any_cert(PyObject * self,PyObject * args)21214 pk11_find_key_by_any_cert(PyObject *self, PyObject *args)
21215 {
21216     Py_ssize_t n_base_args = 1;
21217     Py_ssize_t argc;
21218     PyObject *parse_args = NULL;
21219     Certificate *py_cert = NULL;
21220     PyObject *pin_args = NULL;
21221     SECKEYPrivateKey *private_key;
21222     PyObject *py_private_key = NULL;
21223 
21224     TraceMethodEnter(self);
21225 
21226     argc = PyTuple_Size(args);
21227     if (argc == n_base_args) {
21228         Py_INCREF(args);
21229         parse_args = args;
21230     } else {
21231         parse_args = PyTuple_GetSlice(args, 0, n_base_args);
21232     }
21233     if (!PyArg_ParseTuple(parse_args, "O!:find_key_by_any_cert",
21234                           &CertificateType, &py_cert)) {
21235         Py_DECREF(parse_args);
21236         return NULL;
21237     }
21238     Py_DECREF(parse_args);
21239 
21240     pin_args = PyTuple_GetSlice(args, n_base_args, argc);
21241 
21242     Py_BEGIN_ALLOW_THREADS
21243     if ((private_key = PK11_FindKeyByAnyCert(py_cert->cert, pin_args)) == NULL) {
21244 	Py_BLOCK_THREADS
21245         Py_DECREF(pin_args);
21246         return set_nspr_error(NULL);
21247     }
21248     Py_END_ALLOW_THREADS
21249 
21250     Py_DECREF(pin_args);
21251 
21252     if ((py_private_key = PrivateKey_new_from_SECKEYPrivateKey(private_key)) == NULL) {
21253         return NULL;
21254     }
21255 
21256     return py_private_key;
21257 }
21258 
21259 PyDoc_STRVAR(pk11_generate_random_doc,
21260 "generate_random(num_bytes) -> string\n\
21261 \n\
21262 :Parameters:\n\
21263     num_bytes : integer\n\
21264         Number of num_bytes to generate (must be non-negative)\n\
21265 \n\
21266 Generates random data..\n\
21267 ");
21268 
21269 static PyObject *
pk11_generate_random(PyObject * self,PyObject * args)21270 pk11_generate_random(PyObject *self, PyObject *args)
21271 {
21272     int num_bytes;
21273     unsigned char *buf;
21274     SECStatus status;
21275     PyObject *res;
21276 
21277     TraceMethodEnter(self);
21278 
21279     if (!PyArg_ParseTuple(args, "i:generate_random", &num_bytes))
21280         return NULL;
21281 
21282     if (num_bytes < 0) {
21283         PyErr_SetString(PyExc_ValueError, "byte count must be non-negative");
21284         return NULL;
21285     }
21286 
21287     buf = PyMem_Malloc(num_bytes);
21288     if (buf == NULL) {
21289         return PyErr_NoMemory();
21290     }
21291 
21292     Py_BEGIN_ALLOW_THREADS
21293     status = PK11_GenerateRandom(buf, num_bytes);
21294     Py_END_ALLOW_THREADS
21295     if (status != SECSuccess) {
21296 	PyMem_Free(buf);
21297 	return set_nspr_error(NULL);
21298     }
21299 
21300     res = PyBytes_FromStringAndSize((char *)buf, num_bytes);
21301     PyMem_Free(buf);
21302     return res;
21303 }
21304 
21305 PyDoc_STRVAR(pk11_pk11_need_pw_init_doc,
21306 "pk11_need_pw_init() -> bool\n\
21307 \n\
21308 Returns True if the internal slot needs to be initialized, False otherwise.\n\
21309 \n\
21310 The internal slot token should be initalized if:\n\
21311 \n\
21312 The token is not initialized\n\
21313 \n\
21314    `PK11Slot.need_login()` == True and `PK11Slot.need_user_init()` == True\n\
21315 \n\
21316 Or\n\
21317 \n\
21318 The token has a NULL password.\n\
21319 \n\
21320    `PK11Slot.need_login()` == False and `PK11Slot.need_user_init()` == False\n\
21321 \n\
21322 +------------------+------------------------+---------------------+\n\
21323 |CKF_LOGIN_REQUIRED|CKF_USER_PIN_INITIALIZED|CKF_TOKEN_INITIALIZED|\n\
21324 +==================+========================+=====================+\n\
21325 |      False       |         False          |        True         |\n\
21326 +------------------+------------------------+---------------------+\n\
21327 |       True       |         False          |        False        |\n\
21328 +------------------+------------------------+---------------------+\n\
21329 |      False       |          True          |        True         |\n\
21330 +------------------+------------------------+---------------------+\n\
21331 |       True       |          True          |        True         |\n\
21332 +------------------+------------------------+---------------------+\n\
21333 \n\
21334 `PK11Slot.need_login()` == CKF_LOGIN_REQUIRED\n\
21335 \n\
21336 `PK11Slot.need_user_init()` == !CKF_USER_PIN_INITIALIZED\n\
21337 \n\
21338 ");
21339 
21340 static PyObject *
pk11_pk11_need_pw_init(PyObject * self,PyObject * args,PyObject * kwds)21341 pk11_pk11_need_pw_init(PyObject *self, PyObject *args, PyObject *kwds)
21342 {
21343     TraceMethodEnter(self);
21344 
21345     if (PK11_NeedPWInit())
21346         Py_RETURN_TRUE;
21347     else
21348         Py_RETURN_FALSE;
21349 }
21350 
21351 
21352 
21353 PyDoc_STRVAR(pk11_pk11_token_exists_doc,
21354 "pk11_token_exists(mechanism) -> bool\n\
21355 \n\
21356 :Parameters:\n\
21357     mechanism : int\n\
21358         key mechanism enumeration constant (CKM_*)\n\
21359 \n\
21360 Return True if a token is available which can perform\n\
21361 the desired mechanism, False otherwise.\n\
21362 ");
21363 
21364 static PyObject *
pk11_pk11_token_exists(PyObject * self,PyObject * args)21365 pk11_pk11_token_exists(PyObject *self, PyObject *args)
21366 {
21367     unsigned long mechanism;
21368 
21369     TraceMethodEnter(self);
21370 
21371     if (!PyArg_ParseTuple(args, "k:pk11_token_exists",
21372                           &mechanism))
21373         return NULL;
21374 
21375     if (PK11_TokenExists(mechanism))
21376         Py_RETURN_TRUE;
21377     else
21378         Py_RETURN_FALSE;
21379 
21380 }
21381 
21382 PyDoc_STRVAR(pk11_pk11_is_fips_doc,
21383 "pk11_is_fips() -> bool\n\
21384 \n\
21385 Returns True if the internal module has FIPS enabled, False otherwise.\n\
21386 ");
21387 
21388 static PyObject *
pk11_pk11_is_fips(PyObject * self,PyObject * args,PyObject * kwds)21389 pk11_pk11_is_fips(PyObject *self, PyObject *args, PyObject *kwds)
21390 {
21391     TraceMethodEnter(self);
21392 
21393     if (PK11_IsFIPS())
21394         Py_RETURN_TRUE;
21395     else
21396         Py_RETURN_FALSE;
21397 }
21398 /* ============================== Module Methods ============================= */
21399 
21400 PyDoc_STRVAR(nss_nss_get_version_doc,
21401 "nss_get_version() -> string\n\
21402 \n\
21403 Return a string of the NSS library version\n\
21404 ");
21405 
21406 static PyObject *
nss_nss_get_version(PyObject * self,PyObject * args)21407 nss_nss_get_version(PyObject *self, PyObject *args)
21408 {
21409     const char *nss_version = NULL;
21410 
21411     TraceMethodEnter(self);
21412 
21413     Py_BEGIN_ALLOW_THREADS
21414     if ((nss_version = NSS_GetVersion()) == NULL) {
21415         Py_BLOCK_THREADS
21416         return set_nspr_error(NULL);
21417     }
21418     Py_END_ALLOW_THREADS
21419 
21420     return PyUnicode_FromString(nss_version);
21421 }
21422 
21423 PyDoc_STRVAR(nss_nss_version_check_doc,
21424 "nss_version_check(version) --> bool\n\
21425 \n\
21426 :Parameters:\n\
21427     version : string\n\
21428         Required version\n\
21429 \n\
21430 Return a boolean that indicates whether the underlying NSS library\n\
21431 will perform as the caller expects.\n\
21432 \n\
21433 The the version parameter is a string identifier of the NSS\n\
21434 library. That string will be compared against a string that represents\n\
21435 the actual build version of the NSS library. Return True if supplied\n\
21436 version is compatible, False otherwise.\n\
21437 ");
21438 
21439 static PyObject *
nss_nss_version_check(PyObject * self,PyObject * args)21440 nss_nss_version_check(PyObject *self, PyObject *args)
21441 {
21442     char *version = NULL;
21443     PRBool valid;
21444 
21445     TraceMethodEnter(self);
21446 
21447     if (!PyArg_ParseTuple(args, "s:nss_version_check", &version))
21448         return NULL;
21449 
21450     Py_BEGIN_ALLOW_THREADS
21451     valid = NSS_VersionCheck(version);
21452     Py_END_ALLOW_THREADS
21453 
21454     if (valid) {
21455         Py_RETURN_TRUE;
21456     } else {
21457         Py_RETURN_FALSE;
21458     }
21459 }
21460 
21461 static SECStatus
NSS_Shutdown_Callback(void * app_data,void * nss_data)21462 NSS_Shutdown_Callback(void *app_data, void *nss_data)
21463 {
21464     PyGILState_STATE gstate;
21465     Py_ssize_t n_base_args = 1;
21466     Py_ssize_t argc;
21467     PyObject *shutdown_callback = NULL;
21468     PyObject *callback_args = app_data; /* borrowed reference, don't decrement */
21469     PyObject *item;
21470     PyObject *new_args = NULL;
21471     PyObject *py_nss_data = NULL;
21472     int i, j;
21473     PyObject *py_result = NULL;
21474     SECStatus status_result = SECSuccess;
21475 
21476     gstate = PyGILState_Ensure();
21477 
21478     TraceMessage("NSS_Shutdown_Callback: enter");
21479 
21480     if ((shutdown_callback = get_thread_local("shutdown_callback")) == NULL) {
21481         if (!PyErr_Occurred()) {
21482             PySys_WriteStderr("shutdown callback undefined\n");
21483         } else {
21484             PyErr_Print();
21485         }
21486 	PyGILState_Release(gstate);
21487         return status_result;
21488     }
21489 
21490     argc = n_base_args;
21491     if (callback_args) {
21492         if (PyTuple_Check(callback_args)) {
21493             argc += PyTuple_Size(callback_args);
21494         } else {
21495             PySys_WriteStderr("Error, shutdown callback expected args to be tuple\n");
21496             PyErr_Print();
21497         }
21498     }
21499 
21500     if ((new_args = PyTuple_New(argc)) == NULL) {
21501         PySys_WriteStderr("shutdown callback: out of memory\n");
21502         goto exit;
21503     }
21504 
21505     if ((py_nss_data = PyDict_New()) == NULL){
21506         goto exit;
21507     }
21508 
21509     Py_INCREF(py_nss_data);
21510     PyTuple_SetItem(new_args, 0, py_nss_data);
21511 
21512     for (i = n_base_args, j = 0; i < argc; i++, j++) {
21513         item = PyTuple_GetItem(callback_args, j);
21514         Py_INCREF(item);
21515         PyTuple_SetItem(new_args, i, item);
21516     }
21517 
21518     if ((py_result = PyObject_CallObject(shutdown_callback, new_args)) == NULL) {
21519         PySys_WriteStderr("exception in shutdown callback\n");
21520         PyErr_Print();  /* this also clears the error */
21521         goto exit;
21522     }
21523 
21524     if (PyBool_Check(py_result)) {
21525         status_result = py_result == Py_True ? SECSuccess : SECFailure;
21526     } else {
21527         PySys_WriteStderr("Error, shutdown callback expected int result, not %.50s\n",
21528                       Py_TYPE(py_result)->tp_name);
21529         status_result = SECFailure;
21530         goto exit;
21531     }
21532 
21533  exit:
21534     TraceMessage("NSS_Shutdown_Callback: exiting");
21535 
21536     Py_XDECREF(py_nss_data);
21537     Py_XDECREF(new_args);
21538     Py_XDECREF(py_result);
21539 
21540     PyGILState_Release(gstate);
21541 
21542     return status_result;
21543 }
21544 
21545 PyDoc_STRVAR(nss_set_shutdown_callback_doc,
21546 "set_shutdown_callback(callback, [user_data1, ...])\n\
21547 \n\
21548 :Parameters:\n\
21549     callback : function pointer or None\n\
21550         The callback function. If None cancel the previous callback\n\
21551         \n\
21552     user_dataN : object\n\
21553         zero or more caller supplied parameters which will\n\
21554         be passed to the shutdown callback function\n\
21555 \n\
21556 Defines a callback function which is invoked when NSS is shutdown.\n\
21557 If the callback is None the previous callback is cancelled.\n\
21558 \n\
21559 After NSS is shutdown the shutdown callback is cancelled, you must\n\
21560 reset the shutdown callback again after initializing NSS.\n\
21561 \n\
21562 The callback has the signature::\n\
21563     \n\
21564     shutdown_callback(nss_data, [user_data1, ...]) -> bool\n\
21565 \n\
21566 nss_data\n\
21567     dict of NSS values (currently empty)\n\
21568 user_dataN\n\
21569     zero or more caller supplied optional parameters\n\
21570 \n\
21571 The callback should return True for success. If it returns False the\n\
21572 NSS shutdown function will complete but will result in an error.\n\
21573 ");
21574 static PyObject *
nss_set_shutdown_callback(PyObject * self,PyObject * args)21575 nss_set_shutdown_callback(PyObject *self, PyObject *args)
21576 {
21577     Py_ssize_t n_base_args = 1;
21578     Py_ssize_t argc;
21579     PyObject *parse_args = NULL;
21580     PyObject *new_callback_args = NULL;
21581     PyObject *prev_callback_args = NULL;
21582     PyObject *callback = NULL;
21583 
21584     TraceMethodEnter(self);
21585 
21586     argc = PyTuple_Size(args);
21587     if (argc == n_base_args) {
21588         Py_INCREF(args);
21589         parse_args = args;
21590     } else {
21591         parse_args = PyTuple_GetSlice(args, 0, n_base_args);
21592     }
21593     if (!PyArg_ParseTuple(parse_args, "O:set_shutdown_callback",
21594                           &callback)) {
21595         Py_DECREF(parse_args);
21596         return NULL;
21597     }
21598     Py_DECREF(parse_args);
21599 
21600     new_callback_args = PyTuple_GetSlice(args, n_base_args, argc);
21601 
21602     /*
21603      * PyDict_GetItem() and get_thread_local() return a borrowed
21604      * reference, do not DECREF prev_callback_args.
21605      */
21606     if (PyNone_Check(callback)) {
21607         if ((prev_callback_args = get_thread_local("shutdown_callback_args")) != NULL) {
21608             NSS_UnregisterShutdown(NSS_Shutdown_Callback, prev_callback_args);
21609         }
21610 
21611         del_thread_local("shutdown_callback");
21612         del_thread_local("shutdown_callback_args");
21613 
21614     } else {
21615         if (!PyCallable_Check(callback)) {
21616             PyErr_SetString(PyExc_TypeError, "callback must be callable");
21617             return NULL;
21618         }
21619 
21620         if ((prev_callback_args = get_thread_local("shutdown_callback_args")) != NULL) {
21621             NSS_UnregisterShutdown(NSS_Shutdown_Callback, prev_callback_args);
21622         }
21623 
21624         if (set_thread_local("shutdown_callback", callback) < 0) {
21625             return NULL;
21626         }
21627 
21628         if (set_thread_local("shutdown_callback_args", new_callback_args) < 0) {
21629             return NULL;
21630         }
21631 
21632         NSS_RegisterShutdown(NSS_Shutdown_Callback, new_callback_args);
21633     }
21634 
21635     Py_XDECREF(new_callback_args);
21636 
21637     Py_RETURN_NONE;
21638 }
21639 
21640 PyDoc_STRVAR(nss_nss_is_initialized_doc,
21641 "nss_is_initialized() --> bool\n\
21642 \n\
21643 Returns whether Network Security Services has already been initialized or not.\n\
21644 ");
21645 
21646 static PyObject *
nss_nss_is_initialized(PyObject * self,PyObject * args)21647 nss_nss_is_initialized(PyObject *self, PyObject *args)
21648 {
21649     PRBool is_init;
21650     TraceMethodEnter(self);
21651 
21652     Py_BEGIN_ALLOW_THREADS
21653     is_init = NSS_IsInitialized();
21654     Py_END_ALLOW_THREADS
21655 
21656     if (is_init) {
21657         Py_RETURN_TRUE;
21658     } else {
21659         Py_RETURN_FALSE;
21660     }
21661 }
21662 
21663 PyDoc_STRVAR(nss_nss_init_doc,
21664 "nss_init(cert_dir)\n\
21665 \n\
21666 :Parameters:\n\
21667     cert_dir : string\n\
21668         Pathname of the directory where the certificate, key, and\n\
21669         security module databases reside.\n\
21670 \n\
21671 Sets up configuration files and performs other tasks required to run\n\
21672 Network Security Services. `nss.nss_init()` differs from\n\
21673 `nss.nss_init_read_write()` because the internal PK11 slot (see\n\
21674 `nss.get_internal_slot()`) is created in Read Only (RO) mode as\n\
21675 opposed to Read Write (RW) mode.\n\
21676 ");
21677 
21678 static PyObject *
nss_nss_init(PyObject * self,PyObject * args)21679 nss_nss_init(PyObject *self, PyObject *args)
21680 {
21681     char *cert_dir;
21682 
21683     TraceMethodEnter(self);
21684 
21685     if (!PyArg_ParseTuple(args, "es:nss_init",
21686                           "utf-8", &cert_dir)) {
21687         return NULL;
21688     }
21689 
21690     Py_BEGIN_ALLOW_THREADS
21691     if (NSS_Init(cert_dir) != SECSuccess) {
21692         Py_BLOCK_THREADS
21693         PyMem_Free(cert_dir);
21694         return set_nspr_error(NULL);
21695     }
21696     Py_END_ALLOW_THREADS
21697 
21698     PyMem_Free(cert_dir);
21699     Py_RETURN_NONE;
21700 }
21701 
21702 PyDoc_STRVAR(nss_nss_init_read_write_doc,
21703 "nss_init_read_write(cert_dir)\n\
21704 \n\
21705 :Parameters:\n\
21706     cert_dir : string\n\
21707         Pathname of the directory where the certificate, key, and\n\
21708         security module databases reside.\n\
21709 \n\
21710 Sets up configuration files and performs other tasks required to run\n\
21711 Network Security Services. `nss.nss_init_read_write()` differs from\n\
21712 `nss.nss_init()` because the internal PK11 slot (see\n\
21713 `nss.get_internal_slot()`) is created in Read Write (RW) mode as\n\
21714 opposed to Read Only (RO) mode.\n\
21715 ");
21716 
21717 static PyObject *
nss_nss_init_read_write(PyObject * self,PyObject * args)21718 nss_nss_init_read_write(PyObject *self, PyObject *args)
21719 {
21720     char *cert_dir;
21721 
21722     TraceMethodEnter(self);
21723 
21724     if (!PyArg_ParseTuple(args, "es:nss_init_read_write",
21725                           "utf-8", &cert_dir)) {
21726         return NULL;
21727     }
21728 
21729     Py_BEGIN_ALLOW_THREADS
21730     if (NSS_InitReadWrite(cert_dir) != SECSuccess) {
21731         Py_BLOCK_THREADS
21732         PyMem_Free(cert_dir);
21733         return set_nspr_error(NULL);
21734     }
21735     Py_END_ALLOW_THREADS
21736 
21737     PyMem_Free(cert_dir);
21738     Py_RETURN_NONE;
21739 }
21740 
21741 PyDoc_STRVAR(nss_init_nodb_doc,
21742 "nss_init_nodb()\n\
21743 \n\
21744 Performs tasks required to run Network Security Services without setting up\n\
21745 configuration files. Important: This NSS function is not intended for use with\n\
21746 SSL, which requires that the certificate and key database files be opened.\n\
21747 \n\
21748 nss_init_nodb opens only the temporary database and the internal PKCS #112\n\
21749 module. Unlike nss_init, nss_init_nodb allows applications that do not have\n\
21750 access to storage for databases to run raw crypto, hashing, and certificate\n\
21751 functions. nss_init_nodb is not idempotent, so call it only once. The policy\n\
21752 flags for all cipher suites are turned off by default, disallowing all cipher\n\
21753 suites. Therefore, an application cannot use NSS to perform any cryptographic\n\
21754 operations until after it enables appropriate cipher suites by calling one of\n\
21755 the SSL Export Policy Functions.\n\
21756 ");
21757 
21758 static PyObject *
nss_init_nodb(PyObject * self,PyObject * args)21759 nss_init_nodb(PyObject *self, PyObject *args)
21760 {
21761     TraceMethodEnter(self);
21762 
21763     Py_BEGIN_ALLOW_THREADS
21764     if (NSS_NoDB_Init(NULL) != SECSuccess) {
21765         Py_BLOCK_THREADS
21766         return set_nspr_error(NULL);
21767     }
21768     Py_END_ALLOW_THREADS
21769 
21770     Py_RETURN_NONE;
21771 }
21772 
21773 PyDoc_STRVAR(nss_nss_initialize_doc,
21774 "nss_initialize(cert_dir=None, cert_prefix=None, key_prefix=None, secmod_name=None, flags=0)\n\
21775 \n\
21776 :Parameters:\n\
21777     cert_dir : string\n\
21778         Pathname of the directory where the certificate, key, and\n\
21779         security module databases reside.\n\
21780  \n\
21781     cert_prefix : string\n\
21782         Prefix added to the beginning of the certificate database,\n\
21783         for example,\"https-server1-\".\n\
21784 \n\
21785     key_prefix : string\n\
21786         Prefix added to the beginning of the key database,\n\
21787         for example, \"https-server1-\".\n\
21788 \n\
21789     secmod_name : string\n\
21790         Name of the security module database,\n\
21791         usually \"secmod.db\".\n\
21792 \n\
21793     flags\n\
21794         Bit flags that specify how NSS should be initialized.\n\
21795 \n\
21796 `nss_initialize()` initializes NSS. It is more flexible than `nss_init()`,\n\
21797 `nss_init_read_write()`, and `nss_init_nodb()`. If any of those simpler NSS\n\
21798 initialization functions suffices for your needs, call that instead.\n\
21799 \n\
21800 By default `nss_initialize()` and `nss_init_context()` open the\n\
21801 internal PK11 slot (see `get_internal_slot()`) in Read Write (RW) mode\n\
21802 as opposed to `nss_init()` which opens it in Read Only (RO) mode. If\n\
21803 you want RO mode you pass the `NSS_INIT_READONLY` flag.\n\
21804 \n\
21805 The flags parameter is a bitwise OR of the following flags:\n\
21806 \n\
21807 NSS_INIT_READONLY\n\
21808     Open the databases read only.\n\
21809 \n\
21810 NSS_INIT_NOCERTDB\n\
21811     Don't open the cert DB and key DB's, just initialize the volatile\n\
21812     certdb.\n\
21813 \n\
21814 NSS_INIT_NOMODDB\n\
21815     Don't open the security module DB, just initialize the PKCS #11 module.\n\
21816 \n\
21817 NSS_INIT_FORCEOPEN\n\
21818     Continue to force initializations even if the databases cannot be\n\
21819     opened.\n\
21820 \n\
21821 NSS_INIT_NOROOTINIT\n\
21822     Don't try to look for the root certs module automatically.\n\
21823 \n\
21824 NSS_INIT_OPTIMIZESPACE\n\
21825     Optimize for space instead of speed. Use smaller tables and caches.\n\
21826 \n\
21827 NSS_INIT_PK11THREADSAFE\n\
21828     Only load PKCS#11 modules that are thread-safe, i.e., that support\n\
21829     locking - either OS locking or NSS-provided locks . If a PKCS#11 module\n\
21830     isn't thread-safe, don't serialize its calls; just don't load it\n\
21831     instead. This is necessary if another piece of code is using the same\n\
21832     PKCS#11 modules that NSS is accessing without going through NSS, for\n\
21833     example, the Java SunPKCS11 provider.\n\
21834 \n\
21835 NSS_INIT_PK11RELOAD\n\
21836     Ignore the CKR_CRYPTOKI_ALREADY_INITIALIZED error when loading PKCS#11\n\
21837     modules. This is necessary if another piece of code is using the same\n\
21838     PKCS#11 modules that NSS is accessing without going through NSS, for\n\
21839     example, Java SunPKCS11 provider.\n\
21840 \n\
21841 NSS_INIT_NOPK11FINALIZE\n\
21842     Never call C_Finalize on any PKCS#11 module. This may be necessary in\n\
21843     order to ensure continuous operation and proper shutdown sequence if\n\
21844     another piece of code is using the same PKCS#11 modules that NSS is\n\
21845     accessing without going through NSS, for example, Java SunPKCS11\n\
21846     provider. The following limitation applies when this is set :\n\
21847     SECMOD_WaitForAnyTokenEvent will not use C_WaitForSlotEvent, in order\n\
21848     to prevent the need for C_Finalize. This call will be emulated instead.\n\
21849 \n\
21850 NSS_INIT_RESERVED\n\
21851     Currently has no effect, but may be used in the future to trigger\n\
21852     better cooperation between PKCS#11 modules used by both NSS and the\n\
21853     Java SunPKCS11 provider. This should occur after a new flag is defined\n\
21854     for C_Initialize by the PKCS#11 working group.\n\
21855 \n\
21856 NSS_INIT_COOPERATE\n\
21857     Sets the above four recommended options for applications that use both\n\
21858     NSS and the Java SunPKCS11 provider.\n\
21859 \n\
21860 Hint: You can obtain a printable representation of the flags via `nss_init_flags`.\n\
21861 ");
21862 
21863 static PyObject *
nss_nss_initialize(PyObject * self,PyObject * args,PyObject * kwds)21864 nss_nss_initialize(PyObject *self, PyObject *args, PyObject *kwds)
21865 {
21866     static char *kwlist[] = {"cert_dir", "cert_prefix", "key_prefix", "secmod_name", "flags", NULL};
21867     char *cert_dir = NULL;
21868     char *cert_prefix = NULL;
21869     char *key_prefix = NULL;
21870     char *secmod_name = NULL;
21871     unsigned long flags = 0;
21872     SECStatus status;
21873 
21874 
21875     TraceMethodEnter(self);
21876 
21877     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|esesesesk:nss_initialize", kwlist,
21878                                      "utf-8", &cert_dir,
21879                                      "utf-8", &cert_prefix,
21880                                      "utf-8", &key_prefix,
21881                                      "utf-8", &secmod_name,
21882                                      &flags))
21883         return NULL;
21884 
21885     Py_BEGIN_ALLOW_THREADS
21886     if ((status = NSS_Initialize(cert_dir, cert_prefix, key_prefix, secmod_name, flags)) != SECSuccess) {
21887         set_nspr_error(NULL);
21888     }
21889     Py_END_ALLOW_THREADS
21890 
21891     if (cert_dir)    PyMem_Free(cert_dir);
21892     if (cert_prefix) PyMem_Free(cert_prefix);
21893     if (key_prefix)  PyMem_Free(key_prefix);
21894     if (secmod_name) PyMem_Free(secmod_name);
21895 
21896     if (status == SECSuccess) {
21897         Py_RETURN_NONE;
21898     } else {
21899         return NULL;
21900     }
21901 }
21902 
21903 PyDoc_STRVAR(nss_nss_init_context_doc,
21904 "nss_init_context(cert_dir=None, cert_prefix=None, key_prefix=None, secmod_name=None, init_params=None, flags=0) -> `InitContext`\n\
21905 \n\
21906 :Parameters:\n\
21907     cert_dir : string\n\
21908         Pathname of the directory where the certificate, key, and\n\
21909         security module databases reside.\n\
21910  \n\
21911     cert_prefix : string\n\
21912         Prefix added to the beginning of the certificate database,\n\
21913         for example,\"https-server1-\".\n\
21914 \n\
21915     key_prefix : string\n\
21916         Prefix added to the beginning of the key database,\n\
21917         for example, \"https-server1-\".\n\
21918 \n\
21919     secmod_name : string\n\
21920         Name of the security module database,\n\
21921         usually \"secmod.db\".\n\
21922 \n\
21923     init_params : `InitContext` object\n\
21924         Object with a set of initialization parameters.\n\
21925         See `InitContext`.\n\
21926 \n\
21927     flags\n\
21928         Bit flags that specify how NSS should be initialized.\n\
21929 \n\
21930 `nss_init_context()` initializes NSS within a context and returns a\n\
21931 `InitContext` object. Contexts are used when multiple entities within\n\
21932 a single process wish to use NSS without colliding such as\n\
21933 libraries.\n\
21934 \n\
21935 You must hold onto the returned InitContext object and call shutdown\n\
21936 on it when you are done. The context will automatically be shutdown\n\
21937 when the InitContext object is destroyed if you have not already shut\n\
21938 it down.\n\
21939 \n\
21940 By default `nss_initialize()` and `nss_init_context()` open the\n\
21941 internal PK11 slot (see `get_internal_slot()`) in Read Write (RW) mode\n\
21942 as opposed to `nss_init()` which opens it in Read Only (RO) mode. If\n\
21943 you want RO mode you pass the `NSS_INIT_READONLY` flag.\n\
21944 \n\
21945 The flags parameter is a bitwise OR of the following flags:\n\
21946 \n\
21947 NSS_INIT_READONLY\n\
21948     Open the databases read only.\n\
21949 \n\
21950 NSS_INIT_NOCERTDB\n\
21951     Don't open the cert DB and key DB's, just initialize the volatile\n\
21952     certdb.\n\
21953 \n\
21954 NSS_INIT_NOMODDB\n\
21955     Don't open the security module DB, just initialize the PKCS #11 module.\n\
21956 \n\
21957 NSS_INIT_FORCEOPEN\n\
21958     Continue to force initializations even if the databases cannot be\n\
21959     opened.\n\
21960 \n\
21961 NSS_INIT_NOROOTINIT\n\
21962     Don't try to look for the root certs module automatically.\n\
21963 \n\
21964 NSS_INIT_OPTIMIZESPACE\n\
21965     Optimize for space instead of speed. Use smaller tables and caches.\n\
21966 \n\
21967 NSS_INIT_PK11THREADSAFE\n\
21968     Only load PKCS#11 modules that are thread-safe, i.e., that support\n\
21969     locking - either OS locking or NSS-provided locks . If a PKCS#11 module\n\
21970     isn't thread-safe, don't serialize its calls; just don't load it\n\
21971     instead. This is necessary if another piece of code is using the same\n\
21972     PKCS#11 modules that NSS is accessing without going through NSS, for\n\
21973     example, the Java SunPKCS11 provider.\n\
21974 \n\
21975 NSS_INIT_PK11RELOAD\n\
21976     Ignore the CKR_CRYPTOKI_ALREADY_INITIALIZED error when loading PKCS#11\n\
21977     modules. This is necessary if another piece of code is using the same\n\
21978     PKCS#11 modules that NSS is accessing without going through NSS, for\n\
21979     example, Java SunPKCS11 provider.\n\
21980 \n\
21981 NSS_INIT_NOPK11FINALIZE\n\
21982     Never call C_Finalize on any PKCS#11 module. This may be necessary in\n\
21983     order to ensure continuous operation and proper shutdown sequence if\n\
21984     another piece of code is using the same PKCS#11 modules that NSS is\n\
21985     accessing without going through NSS, for example, Java SunPKCS11\n\
21986     provider. The following limitation applies when this is set :\n\
21987     SECMOD_WaitForAnyTokenEvent will not use C_WaitForSlotEvent, in order\n\
21988     to prevent the need for C_Finalize. This call will be emulated instead.\n\
21989 \n\
21990 NSS_INIT_RESERVED\n\
21991     Currently has no effect, but may be used in the future to trigger\n\
21992     better cooperation between PKCS#11 modules used by both NSS and the\n\
21993     Java SunPKCS11 provider. This should occur after a new flag is defined\n\
21994     for C_Initialize by the PKCS#11 working group.\n\
21995 \n\
21996 NSS_INIT_COOPERATE\n\
21997     Sets the above four recommended options for applications that use both\n\
21998     NSS and the Java SunPKCS11 provider.\n\
21999 \n\
22000 Hint: You can obtain a printable representation of the flags via `nss_init_flags`.\n\
22001 ");
22002 
22003 static PyObject *
nss_nss_init_context(PyObject * self,PyObject * args,PyObject * kwds)22004 nss_nss_init_context(PyObject *self, PyObject *args, PyObject *kwds)
22005 {
22006     static char *kwlist[] = {"cert_dir", "cert_prefix", "key_prefix",
22007                              "secmod_name", "init_params", "flags", NULL};
22008     char *cert_dir = NULL;
22009     char *cert_prefix = NULL;
22010     char *key_prefix = NULL;
22011     char *secmod_name = NULL;
22012     InitParameters *py_init_params = NULL;
22013     unsigned long flags = 0;
22014     NSSInitContext *init_context = NULL;
22015     PyObject *py_init_context = NULL;
22016 
22017     TraceMethodEnter(self);
22018 
22019     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|esesesesO!k:nss_init_context", kwlist,
22020                                      "utf-8", &cert_dir,
22021                                      "utf-8", &cert_prefix,
22022                                      "utf-8", &key_prefix,
22023                                      "utf-8", &secmod_name,
22024                                      &InitParametersType, &py_init_params,
22025                                      &flags))
22026         return NULL;
22027 
22028     if ((init_context = NSS_InitContext(cert_dir, cert_prefix, key_prefix, secmod_name,
22029                                         py_init_params ? &py_init_params->params : NULL,
22030                                         flags)) == NULL) {
22031         set_nspr_error(NULL);
22032     }
22033 
22034     Py_BEGIN_ALLOW_THREADS
22035     if ((py_init_context = InitContext_new_from_NSSInitContext(init_context)) == NULL) {
22036         NSS_ShutdownContext(init_context);
22037         init_context = NULL;
22038     }
22039     Py_END_ALLOW_THREADS
22040 
22041     if (cert_dir)    PyMem_Free(cert_dir);
22042     if (cert_prefix) PyMem_Free(cert_prefix);
22043     if (key_prefix)  PyMem_Free(key_prefix);
22044     if (secmod_name) PyMem_Free(secmod_name);
22045 
22046     if (init_context != NULL) {
22047         return py_init_context;
22048     } else {
22049         return NULL;
22050     }
22051 }
22052 
22053 PyDoc_STRVAR(nss_nss_shutdown_context_doc,
22054 "nss_shutdown_context(context) -> \n\
22055 \n\
22056 :Parameters:\n\
22057     context : `InitContext` object\n\
22058         A `InitContext` returned from a previous\n\
22059         call to `nss_init_context`.\n\
22060 \n\
22061 Shutdown NSS for the users of this context. When all contexts\n\
22062 have been shutdown NSS will fully shutdown.\n\
22063 ");
22064 
22065 static PyObject *
nss_nss_shutdown_context(PyObject * self,PyObject * args)22066 nss_nss_shutdown_context(PyObject *self, PyObject *args)
22067 {
22068     InitContext *py_context = NULL;
22069 
22070     TraceMethodEnter(self);
22071 
22072     if (!PyArg_ParseTuple(args, "O!:nss_shutdown_context",
22073                           &InitContextType, &py_context))
22074         return NULL;
22075 
22076     Py_BEGIN_ALLOW_THREADS
22077     if (NSS_ShutdownContext(py_context->context) != SECSuccess) {
22078         return set_nspr_error(NULL);
22079     }
22080     Py_END_ALLOW_THREADS
22081 
22082     Py_RETURN_NONE;
22083 }
22084 
22085 PyDoc_STRVAR(nss_nss_shutdown_doc,
22086 "nss_shutdown()\n\
22087 \n\
22088 Closes the key and certificate databases that were opened by nss_init().\n\
22089 \n\
22090 NSS can only shutdown successfully if all NSS objects have been\n\
22091 released, otherwise nss_shutdown will fail with the error code\n\
22092 SEC_ERROR_BUSY. Here are some tips to make sure nss_shutdown will\n\
22093 succeed. [1]_\n\
22094 \n\
22095 * If the process is a SSL client make sure you call\n\
22096   `ssl.clear_session_cache`.\n\
22097 \n\
22098 * If the process is a SSL server make sure you call\n\
22099   `ssl.shutdown_server_session_id_cache()`.\n\
22100 \n\
22101 * Make sure all sockets have been closed, open SSL sockets hold\n\
22102   references NSS objects.\n\
22103 \n\
22104 * Explicitly delete Python objects which contain NSS objects using the\n\
22105   del command. [2]_\n\
22106 \n\
22107 * Use `nss.dump_certificate_cache_info()` to provide information about\n\
22108   which cached objects may still persist and be responsible for\n\
22109   preventing a full NSS shutdown.\n\
22110 \n\
22111 .. [1] If the leaked objects are subsequently released after\n\
22112        nss_shutdown is called NSS can be reinitialized with the\n\
22113        various NSS initialization routines. In this cass teh\n\
22114        SEC_ERROR_BUSY error can be thought of as an informatiive\n\
22115        warning.\n\
22116 \n\
22117 .. [2] This Python binding to NSS wraps each NSS object inside a\n\
22118        Python object. Like NSS objects Python objects are reference\n\
22119        counted. When the last reference to the Python object\n\
22120        disappears the Python object is destroyed. The destructor for a\n\
22121        Python object wrapping an NSS object releases the NSS reference\n\
22122        to the NSS object. Thus if any Python objects which wrap NSS\n\
22123        objects remain \"live\" nss_shutdown will fail. Python objects\n\
22124        are typically released by the Python interpretor when the\n\
22125        variable holding the object is assigned a new object or when\n\
22126        the variable holding the object goes out of scope. This means\n\
22127        you may need to manually delete some objects using the del\n\
22128        command rather relying on Python's automatic garbage\n\
22129        collection. Consider this example:\n\
22130 \n\
22131        def foo():\n\
22132            nss.nss_init(certdir)\n\
22133            sock = ssl.SSLSocket()\n\
22134            nss.nss_shutdown()\n\
22135 \n\
22136        When nss_shutown() is called the sock object is still alive and\n\
22137        holds references to NSS objects. The sock object won't be\n\
22138        released by Python until it goes out of scope when the function\n\
22139        exits. Thus the shutdown will fail with SEC_ERROR_BUSY. But you\n\
22140        can explicitly force the sock object to be released by\n\
22141        explictily deleting it, for example:\n\
22142 \n\
22143        def foo():\n\
22144            nss.nss_init(certdir)\n\
22145            sock = ssl.SSLSocket()\n\
22146            del sock\n\
22147            nss.nss_shutdown()\n\
22148 \n\
22149        Another way to avoid this issue is to arrange your code such\n\
22150        that nss_shutdown is called from a location in your code which\n\
22151        is not in scope for any NSS objects created. This also implies\n\
22152        you shouldn't assign NSS objects to globals.\n\
22153 ");
22154 
22155 static PyObject *
nss_nss_shutdown(PyObject * self,PyObject * args)22156 nss_nss_shutdown(PyObject *self, PyObject *args)
22157 {
22158     TraceMethodEnter(self);
22159 
22160     Py_BEGIN_ALLOW_THREADS
22161     if (NSS_Shutdown() != SECSuccess) {
22162         Py_BLOCK_THREADS
22163         return set_nspr_error(NULL);
22164     }
22165     Py_END_ALLOW_THREADS
22166 
22167     Py_RETURN_NONE;
22168 }
22169 
22170 PyDoc_STRVAR(nss_dump_certificate_cache_info_doc,
22171 "dump_certificate_cache_info()\n\
22172 \n\
22173 Dump the contents of the certificate cache and the temporary\n\
22174 cert store to stdout.\n\
22175 \n\
22176 Use this as a debugging aid to detect leaked references of certs at\n\
22177 shutdown time. For example if `nss.nss_shutdown()` throws a\n\
22178 SEC_ERROR_BUSY exception.\n\
22179 ");
22180 
22181 static PyObject *
nss_dump_certificate_cache_info(PyObject * self,PyObject * args)22182 nss_dump_certificate_cache_info(PyObject *self, PyObject *args)
22183 {
22184     TraceMethodEnter(self);
22185 
22186     nss_DumpCertificateCacheInfo();
22187     Py_RETURN_NONE;
22188 }
22189 
22190 PyDoc_STRVAR(cert_oid_str_doc,
22191 "oid_str(oid) -> string\n\
22192 \n\
22193 :Parameters:\n\
22194      oid : may be one of integer, string, SecItem\n\
22195          May be one of:\n\
22196          \n\
22197          * integer:: A SEC OID enumeration constant, also known as a tag\n\
22198            (i.e. SEC_OID_*) for example SEC_OID_AVA_COMMON_NAME.\n\
22199          * string:: A string in dotted decimal representation, for example\n\
22200            'OID.2.5.4.3'. The 'OID.' prefix is optional.\n\
22201            Or a string for the tag name (e.g. 'SEC_OID_AVA_COMMON_NAME')\n\
22202            The 'SEC_OID\\_' prefix is optional. Or one of the canonical\n\
22203            abbreviations (e.g. 'cn'). Case is not significant.\n\
22204          * SecItem:: A SecItem object encapsulating the OID in \n\
22205            DER format.\n\
22206 \n\
22207 Given an oid return it's description as a string.\n\
22208 ");
22209 static PyObject *
cert_oid_str(PyObject * self,PyObject * args)22210 cert_oid_str(PyObject *self, PyObject *args)
22211 {
22212     PyObject *arg;
22213     int oid_tag;
22214     SECOidData *oiddata;
22215 
22216     TraceMethodEnter(self);
22217 
22218    if (!PyArg_ParseTuple(args, "O:oid_str", &arg))
22219         return NULL;
22220 
22221    oid_tag = get_oid_tag_from_object(arg);
22222    if (oid_tag == SEC_OID_UNKNOWN) {
22223        PyErr_Format(PyExc_ValueError, "unable to convert to known OID");
22224        return NULL;
22225    } else if (oid_tag == -1) {
22226        return NULL; /* exception already set */
22227    }
22228 
22229    if ((oiddata = SECOID_FindOIDByTag(oid_tag)) == NULL) {
22230        return set_nspr_error(NULL);
22231    }
22232 
22233    return PyUnicode_FromString(oiddata->desc);
22234 }
22235 
22236 
22237 PyDoc_STRVAR(cert_oid_tag_name_doc,
22238 "oid_tag_name(oid) -> string\n\
22239 \n\
22240 :Parameters:\n\
22241      oid : may be one of integer, string, SecItem\n\
22242          May be one of:\n\
22243          \n\
22244          * integer:: A SEC OID enumeration constant, also known as a tag\n\
22245            (i.e. SEC_OID_*) for example SEC_OID_AVA_COMMON_NAME.\n\
22246          * string:: A string in dotted decimal representation, for example\n\
22247            'OID.2.5.4.3'. The 'OID.' prefix is optional.\n\
22248            Or a string for the tag name (e.g. 'SEC_OID_AVA_COMMON_NAME')\n\
22249            The 'SEC_OID\\_' prefix is optional. Or one of the canonical\n\
22250            abbreviations (e.g. 'cn'). Case is not significant.\n\
22251          * SecItem:: A SecItem object encapsulating the OID in \n\
22252            DER format.\n\
22253 \n\
22254 Given an oid return it's tag constant as a string.\n\
22255 ");
22256 static PyObject *
cert_oid_tag_name(PyObject * self,PyObject * args)22257 cert_oid_tag_name(PyObject *self, PyObject *args)
22258 {
22259     PyObject *arg;
22260     int oid_tag;
22261     PyObject *py_name;
22262 
22263     TraceMethodEnter(self);
22264 
22265     if (!PyArg_ParseTuple(args, "O:oid_tag_name", &arg))
22266         return NULL;
22267 
22268     oid_tag = get_oid_tag_from_object(arg);
22269     if (oid_tag == SEC_OID_UNKNOWN) {
22270         PyErr_Format(PyExc_ValueError, "unable to convert to known OID");
22271         return NULL;
22272     } else if (oid_tag == -1) {
22273         return NULL; /* exception already set */
22274     }
22275 
22276     py_name = oid_tag_to_pystr_name(oid_tag);
22277     return py_name;
22278 }
22279 
22280 PyDoc_STRVAR(cert_oid_tag_doc,
22281 "oid_tag(oid) -> int\n\
22282 \n\
22283 :Parameters:\n\
22284      oid : may be one of integer, string, SecItem\n\
22285          May be one of:\n\
22286          \n\
22287          * integer:: A SEC OID enumeration constant, also known as a tag\n\
22288            (i.e. SEC_OID_*) for example SEC_OID_AVA_COMMON_NAME.\n\
22289          * string:: A string in dotted decimal representation, for example\n\
22290            'OID.2.5.4.3'. The 'OID.' prefix is optional.\n\
22291            Or a string for the tag name (e.g. 'SEC_OID_AVA_COMMON_NAME')\n\
22292            The 'SEC_OID\\_' prefix is optional. Or one of the canonical\n\
22293            abbreviations (e.g. 'cn'). Case is not significant.\n\
22294          * SecItem:: A SecItem object encapsulating the OID in \n\
22295            DER format.\n\
22296 \n\
22297 Given an oid return it's tag constant.\n\
22298 ");
22299 static PyObject *
cert_oid_tag(PyObject * self,PyObject * args)22300 cert_oid_tag(PyObject *self, PyObject *args)
22301 {
22302     PyObject *result;
22303     PyObject *arg;
22304     int oid_tag;
22305 
22306     TraceMethodEnter(self);
22307 
22308     if (!PyArg_ParseTuple(args, "O:oid_tag", &arg))
22309         return NULL;
22310 
22311     oid_tag = get_oid_tag_from_object(arg);
22312     if (oid_tag == SEC_OID_UNKNOWN) {
22313         PyErr_Format(PyExc_ValueError, "unable to convert to known OID");
22314         return NULL;
22315     } else if (oid_tag == -1) {
22316         return NULL; /* exception already set */
22317     }
22318 
22319     result = PyLong_FromLong(oid_tag);
22320     return result;
22321 }
22322 
22323 PyDoc_STRVAR(cert_oid_dotted_decimal_doc,
22324 "oid_dotted_decimal(oid) -> string\n\
22325 \n\
22326 :Parameters:\n\
22327      oid : may be one of integer, string, SecItem\n\
22328          May be one of:\n\
22329          \n\
22330          * integer:: A SEC OID enumeration constant, also known as a tag\n\
22331            (i.e. SEC_OID_*) for example SEC_OID_AVA_COMMON_NAME.\n\
22332          * string:: A string in dotted decimal representation, for example\n\
22333            'OID.2.5.4.3'. The 'OID.' prefix is optional.\n\
22334            Or a string for the tag name (e.g. 'SEC_OID_AVA_COMMON_NAME')\n\
22335            The 'SEC_OID\\_' prefix is optional. Or one of the canonical\n\
22336            abbreviations (e.g. 'cn'). Case is not significant.\n\
22337          * SecItem:: A SecItem object encapsulating the OID in \n\
22338            DER format.\n\
22339 \n\
22340 Given an oid return it's tag constant as a string.\n\
22341 ");
22342 static PyObject *
cert_oid_dotted_decimal(PyObject * self,PyObject * args)22343 cert_oid_dotted_decimal(PyObject *self, PyObject *args)
22344 {
22345     PyObject *arg;
22346     int oid_tag;
22347     SECOidData *oiddata;
22348 
22349     TraceMethodEnter(self);
22350 
22351     if (!PyArg_ParseTuple(args, "O:oid_dotted_decimal", &arg))
22352         return NULL;
22353 
22354     if (PySecItem_Check(arg)) {
22355         return oid_secitem_to_pystr_dotted_decimal(&((SecItem *)arg)->item);
22356     }
22357 
22358     oid_tag = get_oid_tag_from_object(arg);
22359 
22360     if (oid_tag == SEC_OID_UNKNOWN) {
22361         PyErr_Format(PyExc_ValueError, "unable to convert to known OID");
22362         return NULL;
22363     } else if (oid_tag == -1) {
22364         return NULL; /* exception already set */
22365     }
22366 
22367     if ((oiddata = SECOID_FindOIDByTag(oid_tag)) == NULL) {
22368         return set_nspr_error(NULL);
22369     }
22370 
22371     return oid_secitem_to_pystr_dotted_decimal(&oiddata->oid);
22372 }
22373 
22374 
22375 static PyObject *
key_mechanism_type_to_pystr(CK_MECHANISM_TYPE mechanism)22376 key_mechanism_type_to_pystr(CK_MECHANISM_TYPE mechanism)
22377 {
22378     PyObject *py_value;
22379     PyObject *py_name;
22380 
22381     if ((py_value = PyLong_FromLong(mechanism)) == NULL) {
22382         PyErr_SetString(PyExc_MemoryError, "unable to create object");
22383         return NULL;
22384     }
22385 
22386     if ((py_name = PyDict_GetItem(ckm_value_to_name, py_value)) == NULL) {
22387         Py_DECREF(py_value);
22388 	PyErr_Format(PyExc_KeyError, "mechanism name not found: %lu", mechanism);
22389         return NULL;
22390     }
22391 
22392     Py_DECREF(py_value);
22393     Py_INCREF(py_name);
22394 
22395     return py_name;
22396 }
22397 
22398 PyDoc_STRVAR(pk11_key_mechanism_type_name_doc,
22399 "key_mechanism_type_name(mechanism) -> string\n\
22400 \n\
22401 :Parameters:\n\
22402     mechanism : int\n\
22403         key mechanism enumeration constant (CKM_*)\n\
22404 \n\
22405 Given a key mechanism enumeration constant (CKM_*)\n\
22406 return it's name as a string\n\
22407 ");
22408 static PyObject *
pk11_key_mechanism_type_name(PyObject * self,PyObject * args)22409 pk11_key_mechanism_type_name(PyObject *self, PyObject *args)
22410 {
22411     unsigned long mechanism;
22412 
22413     TraceMethodEnter(self);
22414 
22415     if (!PyArg_ParseTuple(args, "k:key_mechanism_type_name", &mechanism))
22416         return NULL;
22417 
22418     return key_mechanism_type_to_pystr(mechanism);
22419 }
22420 
22421 PyDoc_STRVAR(pk11_key_mechanism_type_from_name_doc,
22422 "key_mechanism_type_from_name(name) -> int\n\
22423 \n\
22424 :Parameters:\n\
22425     name : string\n\
22426         name of key mechanism enumeration constant (CKM_*)\n\
22427 \n\
22428 Given the name of a key mechanism enumeration constant (CKM_*)\n\
22429 return it's integer constant\n\
22430 The string comparison is case insensitive and will match with\n\
22431 or without the CKM\\_ prefix\n\
22432 ");
22433 static PyObject *
pk11_key_mechanism_type_from_name(PyObject * self,PyObject * args)22434 pk11_key_mechanism_type_from_name(PyObject *self, PyObject *args)
22435 {
22436     PyObject *py_name;
22437     PyObject *py_lower_name;
22438     PyObject *py_value;
22439 
22440     TraceMethodEnter(self);
22441 
22442     if (!PyArg_ParseTuple(args, "S:key_mechanism_type_from_name", &py_name))
22443         return NULL;
22444 
22445     if ((py_lower_name = PyUnicode_Lower(py_name)) == NULL) {
22446         return NULL;
22447     }
22448 
22449     if ((py_value = PyDict_GetItem(ckm_name_to_value, py_lower_name)) == NULL) {
22450         PyObject *py_name_utf8 = PyBaseString_UTF8(py_name, "mechanism name");
22451 	PyErr_Format(PyExc_KeyError, "mechanism name not found: %s", PyBytes_AsString(py_name_utf8));
22452         Py_DECREF(py_lower_name);
22453         Py_XDECREF(py_name_utf8);
22454         return NULL;
22455     }
22456 
22457     Py_DECREF(py_lower_name);
22458     Py_INCREF(py_value);
22459 
22460     return py_value;
22461 }
22462 
22463 static PyObject *
pk11_attribute_type_to_pystr(CK_ATTRIBUTE_TYPE type)22464 pk11_attribute_type_to_pystr(CK_ATTRIBUTE_TYPE type)
22465 {
22466     PyObject *py_value;
22467     PyObject *py_name;
22468 
22469     if ((py_value = PyLong_FromLong(type)) == NULL) {
22470         PyErr_SetString(PyExc_MemoryError, "unable to create object");
22471         return NULL;
22472     }
22473 
22474     if ((py_name = PyDict_GetItem(cka_value_to_name, py_value)) == NULL) {
22475         Py_DECREF(py_value);
22476 	PyErr_Format(PyExc_KeyError, "attribute type name not found: %lu", type);
22477         return NULL;
22478     }
22479 
22480     Py_DECREF(py_value);
22481     Py_INCREF(py_name);
22482 
22483     return py_name;
22484 }
22485 
22486 PyDoc_STRVAR(pk11_attribute_type_name_doc,
22487 "pk11_attribute_type_name(type) -> string\n\
22488 \n\
22489 :Parameters:\n\
22490     type : int\n\
22491         PK11 attribute type constant (CKA_*)\n\
22492 \n\
22493 Given a PK11 attribute type constant (CKA_*)\n\
22494 return it's name as a string\n\
22495 ");
22496 static PyObject *
pk11_pk11_attribute_type_name(PyObject * self,PyObject * args)22497 pk11_pk11_attribute_type_name(PyObject *self, PyObject *args)
22498 {
22499     unsigned long type;
22500 
22501     TraceMethodEnter(self);
22502 
22503     if (!PyArg_ParseTuple(args, "k:pk11_attribute_type_name", &type))
22504         return NULL;
22505 
22506     return pk11_attribute_type_to_pystr(type);
22507 }
22508 
22509 PyDoc_STRVAR(pk11_pk11_attribute_type_from_name_doc,
22510 "pk11_attribute_type_from_name(name) -> int\n\
22511 \n\
22512 :Parameters:\n\
22513     name : string\n\
22514         name of PK11 attribute type constant (CKA_*)\n\
22515 \n\
22516 Given the name of a PK11 attribute type constant (CKA_*)\n\
22517 return it's integer constant\n\
22518 The string comparison is case insensitive and will match with\n\
22519 or without the CKA\\_ prefix\n\
22520 ");
22521 static PyObject *
pk11_pk11_attribute_type_from_name(PyObject * self,PyObject * args)22522 pk11_pk11_attribute_type_from_name(PyObject *self, PyObject *args)
22523 {
22524     PyObject *py_name;
22525     PyObject *py_lower_name;
22526     PyObject *py_value;
22527 
22528     TraceMethodEnter(self);
22529 
22530     if (!PyArg_ParseTuple(args, "S:pk11_attribute_type_from_name", &py_name))
22531         return NULL;
22532 
22533     if ((py_lower_name = PyUnicode_Lower(py_name)) == NULL) {
22534         return NULL;
22535     }
22536 
22537     if ((py_value = PyDict_GetItem(cka_name_to_value, py_lower_name)) == NULL) {
22538         PyObject *py_name_utf8 = PyBaseString_UTF8(py_name, "attribute name");
22539 	PyErr_Format(PyExc_KeyError, "attribute name not found: %s", PyBytes_AsString(py_name_utf8));
22540         Py_DECREF(py_lower_name);
22541         Py_XDECREF(py_name_utf8);
22542         return NULL;
22543     }
22544 
22545     Py_DECREF(py_lower_name);
22546     Py_INCREF(py_value);
22547 
22548     return py_value;
22549 }
22550 
22551 PyDoc_STRVAR(pk11_disabled_reason_str_doc,
22552 "pk11_disabled_reason_str(reason) -> string\n\
22553 \n\
22554 :Parameters:\n\
22555     reason : int\n\
22556         PK11 slot disabled reason constant (PK11_DIS_*)\n\
22557 \n\
22558 Given a PK11 slot disabled reason constant (PK11_DIS_*)\n\
22559 return a descriptive string\n\
22560 ");
22561 static PyObject *
pk11_pk11_disabled_reason_str(PyObject * self,PyObject * args)22562 pk11_pk11_disabled_reason_str(PyObject *self, PyObject *args)
22563 {
22564     unsigned long reason;
22565 
22566     TraceMethodEnter(self);
22567 
22568     if (!PyArg_ParseTuple(args, "k:pk11_disabled_reason_str", &reason))
22569         return NULL;
22570 
22571     return PyUnicode_FromString(pk11_disabled_reason_str(reason));
22572 }
22573 
22574 PyDoc_STRVAR(pk11_disabled_reason_name_doc,
22575 "pk11_disabled_reason_name(reason) -> string\n\
22576 \n\
22577 :Parameters:\n\
22578     reason : int\n\
22579         PK11 slot disabled reason constant (PK11_DIS_*)\n\
22580 \n\
22581 Given a PK11 slot disabled reason constant (PK11_DIS_*)\n\
22582 return the constant as a string.\n\
22583 ");
22584 static PyObject *
pk11_pk11_disabled_reason_name(PyObject * self,PyObject * args)22585 pk11_pk11_disabled_reason_name(PyObject *self, PyObject *args)
22586 {
22587     unsigned long reason;
22588 
22589     TraceMethodEnter(self);
22590 
22591     if (!PyArg_ParseTuple(args, "k:pk11_disabled_reason_name", &reason))
22592         return NULL;
22593 
22594     return PyUnicode_FromString(pk11_disabled_reason_name(reason));
22595 }
22596 
22597 PyDoc_STRVAR(pk11_pk11_logout_all_doc,
22598 "pk11_logout_all()\n\
22599 \n\
22600 Logout of every slot for all modules.\n\
22601 ");
22602 static PyObject *
pk11_pk11_logout_all(PK11Slot * self,PyObject * args)22603 pk11_pk11_logout_all(PK11Slot *self, PyObject *args)
22604 {
22605     TraceMethodEnter(self);
22606 
22607     PK11_LogoutAll();
22608     Py_RETURN_NONE;
22609 }
22610 
22611 PyDoc_STRVAR(pk11_get_best_slot_doc,
22612 "get_best_slot(mechanism, [user_data1, ...]) -> PK11Slot\n\
22613 \n\
22614 :Parameters:\n\
22615     mechanism : int\n\
22616         key mechanism enumeration constant (CKM_*)\n\
22617     user_dataN : object ...\n\
22618         zero or more caller supplied parameters which will\n\
22619         be passed to the password callback function\n\
22620 \n\
22621 Find the best slot which supports the given mechanism.\n\
22622 ");
22623 
22624 static PyObject *
pk11_get_best_slot(PyObject * self,PyObject * args)22625 pk11_get_best_slot(PyObject *self, PyObject *args)
22626 {
22627     Py_ssize_t n_base_args = 1;
22628     Py_ssize_t argc;
22629     PyObject *parse_args = NULL;
22630     PyObject *pin_args = NULL;
22631     unsigned long mechanism;
22632     PK11SlotInfo *slot = NULL;
22633     PyObject *py_slot = NULL;
22634 
22635     TraceMethodEnter(self);
22636 
22637     argc = PyTuple_Size(args);
22638     if (argc == n_base_args) {
22639         Py_INCREF(args);
22640         parse_args = args;
22641     } else {
22642         parse_args = PyTuple_GetSlice(args, 0, n_base_args);
22643     }
22644     if (!PyArg_ParseTuple(parse_args, "k:get_best_slot", &mechanism)) {
22645         Py_DECREF(parse_args);
22646         return NULL;
22647     }
22648     Py_DECREF(parse_args);
22649 
22650     pin_args = PyTuple_GetSlice(args, n_base_args, argc);
22651 
22652     Py_BEGIN_ALLOW_THREADS
22653     if ((slot = PK11_GetBestSlot(mechanism, pin_args)) == NULL) {
22654 	Py_BLOCK_THREADS
22655         Py_DECREF(pin_args);
22656         return set_nspr_error(NULL);
22657     }
22658     Py_END_ALLOW_THREADS
22659 
22660     Py_DECREF(pin_args);
22661 
22662     if ((py_slot = PK11Slot_new_from_PK11SlotInfo(slot)) == NULL) {
22663         PyErr_SetString(PyExc_MemoryError, "unable to create PK11Slot object");
22664         return NULL;
22665     }
22666 
22667     return py_slot;
22668 }
22669 
22670 PyDoc_STRVAR(pk11_get_internal_slot_doc,
22671 "get_internal_slot() -> PK11Slot\n\
22672 \n\
22673 Get the default internal slot.\n\
22674 ");
22675 
22676 static PyObject *
pk11_get_internal_slot(PyObject * self,PyObject * args)22677 pk11_get_internal_slot(PyObject *self, PyObject *args)
22678 {
22679     PK11SlotInfo *slot = NULL;
22680     PyObject *py_slot = NULL;
22681 
22682     TraceMethodEnter(self);
22683 
22684     if ((slot = PK11_GetInternalSlot()) == NULL) {
22685         return set_nspr_error(NULL);
22686     }
22687 
22688     if ((py_slot = PK11Slot_new_from_PK11SlotInfo(slot)) == NULL) {
22689         PyErr_SetString(PyExc_MemoryError, "unable to create PK11Slot object");
22690         return NULL;
22691     }
22692 
22693     return py_slot;
22694 }
22695 
22696 PyDoc_STRVAR(pk11_get_internal_key_slot_doc,
22697 "get_internal_key_slot() -> PK11Slot\n\
22698 \n\
22699 Get the default internal key slot.\n\
22700 ");
22701 
22702 static PyObject *
pk11_get_internal_key_slot(PyObject * self,PyObject * args)22703 pk11_get_internal_key_slot(PyObject *self, PyObject *args)
22704 {
22705     PK11SlotInfo *slot = NULL;
22706     PyObject *py_slot = NULL;
22707 
22708     TraceMethodEnter(self);
22709 
22710     if ((slot = PK11_GetInternalKeySlot()) == NULL) {
22711         return set_nspr_error(NULL);
22712     }
22713 
22714     if ((py_slot = PK11Slot_new_from_PK11SlotInfo(slot)) == NULL) {
22715         PyErr_SetString(PyExc_MemoryError, "unable to create PK11Slot object");
22716         return NULL;
22717     }
22718 
22719     return py_slot;
22720 }
22721 
22722 
22723 PyDoc_STRVAR(pk11_get_all_tokens_doc,
22724 "get_all_tokens(mechanism=CKM_INVALID_MECHANISM, need_rw=False, load_certs=False, pin_args=None) -> (PK11Slot, ...)\n\
22725 \n\
22726 :Parameters:\n\
22727     mechanism : int\n\
22728         key mechanism enumeration constant (CKM_*).\n\
22729         Use CKM_INVALID_MECHANISM to get all tokens.\n\
22730     need_rw : boolean\n\
22731         need read/write\n\
22732     load_certs : boolean\n\
22733         load certificates\n\
22734     pin_args : tuple\n\
22735         Extra parameters which will\n\
22736         be passed to the password callback function.\n\
22737 \n\
22738 Return a tuple of PK11Slot objects.\n\
22739 \n\
22740 Example::\n\
22741 \n\
22742     import nss.nss as nss\n\
22743     nss.nss_init_nodb()\n\
22744 \n\
22745     slots = nss.get_all_tokens()\n\
22746     for slot in slots:\n\
22747         print slot\n\
22748         print\n\
22749 \n\
22750     Slot Name:                         NSS User Private Key and Certificate Services\n\
22751     Token Name:                        NSS Certificate DB\n\
22752     Is Hardware:                       False\n\
22753     Is Present:                        True\n\
22754     Is Read Only:                      True\n\
22755     Is Internal:                       True\n\
22756     Needs Login:                       False\n\
22757     Needs User Init:                   True\n\
22758     Is Friendly:                       True\n\
22759     Is Removable:                      False\n\
22760     Has Protected Authentication Path: False\n\
22761     Is Disabled:                       False (no reason)\n\
22762     Has Root Certs:                    False\n\
22763     Best Wrap Mechanism:               CKM_DES3_ECB (0x132)\n\
22764 \n\
22765     Slot Name:                         NSS Internal Cryptographic Services\n\
22766     Token Name:                        NSS Generic Crypto Services\n\
22767     Is Hardware:                       False\n\
22768     Is Present:                        True\n\
22769     Is Read Only:                      True\n\
22770     Is Internal:                       True\n\
22771     Needs Login:                       False\n\
22772     Needs User Init:                   True\n\
22773     Is Friendly:                       True\n\
22774     Is Removable:                      False\n\
22775     Has Protected Authentication Path: False\n\
22776     Is Disabled:                       False (no reason)\n\
22777     Has Root Certs:                    False\n\
22778     Best Wrap Mechanism:               CKM_DES3_ECB (0x132)\n\
22779 \n\
22780 ");
22781 
22782 static PyObject *
pk11_get_all_tokens(PyObject * self,PyObject * args,PyObject * kwds)22783 pk11_get_all_tokens(PyObject *self, PyObject *args, PyObject *kwds)
22784 {
22785     static char *kwlist[] = {"mechanism", "need_rw", "load_certs", "pin_args", NULL};
22786     unsigned long mechanism = CKM_INVALID_MECHANISM;
22787     int need_rw = 0;
22788     int load_certs = 0;
22789     PyObject *pin_args = Py_None;
22790     PyObject *tuple = NULL;
22791     PK11SlotList *list = NULL;
22792 
22793 
22794     TraceMethodEnter(self);
22795 
22796     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|kiiO&:get_all_tokens", kwlist,
22797                                      &mechanism, &need_rw, &load_certs,
22798                                      TupleOrNoneConvert, &pin_args))
22799         return NULL;
22800 
22801     if (PyNone_Check(pin_args)) {
22802         pin_args = NULL;
22803     }
22804 
22805     if ((list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_FALSE, pin_args)) == NULL) {
22806         return set_nspr_error(NULL);
22807     }
22808 
22809     tuple = PK11SlotList_to_tuple(list);
22810     PK11_FreeSlotList(list);
22811 
22812     return tuple;
22813 }
22814 
22815 
22816 PyDoc_STRVAR(pk11_find_slot_by_name_doc,
22817 "find_slot_by_name(name) -> `PK11Slot`\n\
22818 \n\
22819 :Parameters:\n\
22820     name : string\n\
22821         slot name\n\
22822 \n\
22823 Given a slot name return a `PK11Slot` object.\n\
22824 ");
22825 
22826 static PyObject *
pk11_find_slot_by_name(PyObject * self,PyObject * args)22827 pk11_find_slot_by_name(PyObject *self, PyObject *args)
22828 {
22829     char *slot_name = NULL;
22830     PK11SlotInfo *slot = NULL;
22831     PyObject *py_slot = NULL;
22832 
22833     TraceMethodEnter(self);
22834 
22835     if (!PyArg_ParseTuple(args, "es:find_slot_by_name",
22836                           "utf-8", &slot_name))
22837         return NULL;
22838 
22839     if ((slot = PK11_FindSlotByName(slot_name)) == NULL) {
22840         PyMem_Free(slot_name);
22841         return set_nspr_error("could not find slot name \"%s\"", slot_name);
22842     }
22843     PyMem_Free(slot_name);
22844 
22845     if ((py_slot = PK11Slot_new_from_PK11SlotInfo(slot)) == NULL) {
22846         PyErr_SetString(PyExc_MemoryError, "unable to create PK11Slot object");
22847         return NULL;
22848     }
22849 
22850     return py_slot;
22851 }
22852 
22853 PyDoc_STRVAR(pk11_create_context_by_sym_key_doc,
22854 "create_context_by_sym_key(mechanism, operation, sym_key, sec_param=None) -> PK11Context\n\
22855 \n\
22856 :Parameters:\n\
22857     mechanism : int\n\
22858         key mechanism enumeration constant (CKM_*)\n\
22859     operation : int\n\
22860         type of operation this context will be doing. A (CKA_*) constant\n\
22861         (e.g. CKA_ENCRYPT, CKA_DECRYPT, CKA_SIGN, CKA_VERIFY, CKA_DIGEST)\n\
22862     sym_key : PK11SymKey object\n\
22863         symmetric key\n\
22864     sec_param : SecItem object or None\n\
22865         mechanism parameters used to build this context or None.\n\
22866 \n\
22867 Create a context from a symmetric key)\n\
22868 ");
22869 static PyObject *
pk11_create_context_by_sym_key(PyObject * self,PyObject * args,PyObject * kwds)22870 pk11_create_context_by_sym_key(PyObject *self, PyObject *args, PyObject *kwds)
22871 {
22872     static char *kwlist[] = {"mechanism", "operation", "sym_key", "sec_param", NULL};
22873     unsigned long mechanism;
22874     unsigned long operation;
22875     PyPK11SymKey *py_sym_key;
22876     SecItem *py_sec_param;
22877     PK11Context *pk11_context;
22878     PyObject *py_pk11_context;
22879     SECItem null_param = {0};
22880 
22881     TraceMethodEnter(self);
22882 
22883     if (!PyArg_ParseTupleAndKeywords(args, kwds, "kkO!|O&:create_context_by_sym_key", kwlist,
22884                                      &mechanism, &operation,
22885                                      &PK11SymKeyType, &py_sym_key,
22886                                      SecItemOrNoneConvert, &py_sec_param))
22887         return NULL;
22888 
22889     if ((pk11_context =
22890          PK11_CreateContextBySymKey(mechanism, operation, py_sym_key->pk11_sym_key,
22891                                     py_sec_param ? &py_sec_param->item : &null_param)) == NULL) {
22892         return set_nspr_error(NULL);
22893     }
22894 
22895     if ((py_pk11_context = PyPK11Context_new_from_PK11Context(pk11_context)) == NULL) {
22896         PyErr_SetString(PyExc_MemoryError, "unable to create PK11Context object");
22897         return NULL;
22898     }
22899 
22900     return py_pk11_context;
22901 }
22902 
22903 PyDoc_STRVAR(pk11_import_sym_key_doc,
22904 "import_sym_key(slot, mechanism, origin, operation, key_data, [user_data1, ...]) -> PK11SymKey\n\
22905 \n\
22906 :Parameters:\n\
22907     slot : PK11Slot object\n\
22908         designated PK11 slot\n\
22909     mechanism : int\n\
22910         key mechanism enumeration constant (CKM_*)\n\
22911     origin : int\n\
22912         PK11 origin enumeration (PK11Origin*)\n\
22913         e.g. PK11_OriginDerive, PK11_OriginUnwrap, etc.\n\
22914     operation : int\n\
22915         type of operation this context will be doing. A (CKA_*) constant\n\
22916         (e.g. CKA_ENCRYPT, CKA_DECRYPT, CKA_SIGN, CKA_VERIFY, CKA_DIGEST)\n\
22917     key_data: SecItem object\n\
22918         key data encapsulated in a SECItem used to build the symmetric key.\n\
22919     user_dataN : object ...\n\
22920         zero or more caller supplied parameters which will\n\
22921         be passed to the password callback function\n\
22922 \n\
22923 Create a PK11SymKey from data)\n\
22924 ");
22925 static PyObject *
pk11_import_sym_key(PyObject * self,PyObject * args)22926 pk11_import_sym_key(PyObject *self, PyObject *args)
22927 {
22928     Py_ssize_t n_base_args = 5;
22929     Py_ssize_t argc;
22930     PyObject *parse_args = NULL;
22931     PyObject *pin_args = NULL;
22932     PK11Slot *py_slot;
22933     unsigned long mechanism;
22934     unsigned long origin;
22935     unsigned long operation;
22936     SecItem *py_key_data;
22937     PK11SymKey *sym_key;
22938 
22939     TraceMethodEnter(self);
22940 
22941     argc = PyTuple_Size(args);
22942     if (argc == n_base_args) {
22943         Py_INCREF(args);
22944         parse_args = args;
22945     } else {
22946         parse_args = PyTuple_GetSlice(args, 0, n_base_args);
22947     }
22948 
22949     if (!PyArg_ParseTuple(parse_args, "O!kkkO!:import_sym_key",
22950                           &PK11SlotType, &py_slot,
22951                           &mechanism, &origin, &operation,
22952                           &SecItemType, &py_key_data)) {
22953         Py_DECREF(parse_args);
22954         return NULL;
22955     }
22956     Py_DECREF(parse_args);
22957 
22958     pin_args = PyTuple_GetSlice(args, n_base_args, argc);
22959 
22960     Py_BEGIN_ALLOW_THREADS
22961     if ((sym_key = PK11_ImportSymKey(py_slot->slot, mechanism, origin, operation,
22962                                      &py_key_data->item, pin_args)) == NULL) {
22963 	Py_BLOCK_THREADS
22964         Py_DECREF(pin_args);
22965         return set_nspr_error(NULL);
22966     }
22967     Py_END_ALLOW_THREADS
22968 
22969     Py_DECREF(pin_args);
22970 
22971     return PyPK11SymKey_new_from_PK11SymKey(sym_key);
22972 }
22973 
22974 PyDoc_STRVAR(pk11_pub_wrap_sym_key_doc,
22975 "pub_wrap_sym_key(mechanism, pub_key, sym_key) -> SecItem\n\
22976 \n\
22977 :Parameters:\n\
22978     mechanism : int\n\
22979         CK_MECHANISM_TYPE enumerated constant\n\
22980     pub_key : `PublicKey` object\n\
22981         Public key used to wrap.\n\
22982     sym_key : `PK11SymKey` object\n\
22983         Symmetric key that will be wrapped.\n\
22984 :returns:\n\
22985     Wrapped symmetric key as SecItem\n\
22986 \n\
22987 Wraps a public key wrap (which only RSA can do).\n\
22988 ");
22989 static PyObject *
pk11_pub_wrap_sym_key(PyObject * self,PyObject * args)22990 pk11_pub_wrap_sym_key(PyObject *self, PyObject *args)
22991 {
22992     unsigned long mechanism;
22993     PublicKey *py_pub_key = NULL;
22994     PyPK11SymKey *py_sym_key = NULL;
22995     size_t key_len = 0;
22996     SecItem  *py_wrapped_key = NULL;
22997 
22998     TraceMethodEnter(self);
22999 
23000     if (!PyArg_ParseTuple(args, "kO!O!:pub_wrap_sym_key",
23001                           &mechanism,
23002                           &PublicKeyType, &py_pub_key,
23003                           &PK11SymKeyType, &py_sym_key))
23004         return NULL;
23005 
23006     key_len = SECKEY_PublicKeyStrength(py_pub_key->pk);
23007     if ((py_wrapped_key = (SecItem *)SecItem_new_alloc(key_len, siBuffer, SECITEM_wrapped_key)) == NULL) {
23008         return NULL;
23009     }
23010 
23011     Py_BEGIN_ALLOW_THREADS
23012     if ((PK11_PubWrapSymKey(mechanism, py_pub_key->pk, py_sym_key->pk11_sym_key,
23013                             &py_wrapped_key->item) != SECSuccess)) {
23014 	Py_BLOCK_THREADS
23015         Py_CLEAR(py_wrapped_key);
23016         return set_nspr_error(NULL);
23017     }
23018     Py_END_ALLOW_THREADS
23019 
23020     return (PyObject *)py_wrapped_key;
23021 }
23022 
23023 PyDoc_STRVAR(pk11_create_digest_context_doc,
23024 "create_digest_context(hash_alg) -> PK11Context\n\
23025 \n\
23026 :Parameters:\n\
23027     hash_alg : int\n\
23028         hash algorithm enumeration (SEC_OID_*)\n\
23029         e.g.: SEC_OID_MD5, SEC_OID_SHA1, SEC_OID_SHA256, SEC_OID_SHA512, etc.\n\
23030 \n\
23031 Create a context for performing digest (hash) operations)\n\
23032 ");
23033 static PyObject *
pk11_create_digest_context(PyObject * self,PyObject * args)23034 pk11_create_digest_context(PyObject *self, PyObject *args)
23035 {
23036     unsigned long hash_alg;
23037     PK11Context *pk11_context;
23038     PyObject *py_pk11_context;
23039 
23040     TraceMethodEnter(self);
23041 
23042     if (!PyArg_ParseTuple(args, "k:create_digest_context", &hash_alg))
23043         return NULL;
23044 
23045     if ((pk11_context = PK11_CreateDigestContext(hash_alg)) == NULL) {
23046         return set_nspr_error(NULL);
23047     }
23048 
23049     if ((py_pk11_context =
23050          PyPK11Context_new_from_PK11Context(pk11_context)) == NULL) {
23051         PyErr_SetString(PyExc_MemoryError, "unable to create PK11Context object");
23052         return NULL;
23053     }
23054 
23055     return py_pk11_context;
23056 }
23057 
23058 PyDoc_STRVAR(pk11_param_from_iv_doc,
23059 "param_from_iv(mechanism, iv=None) -> SecItem\n\
23060 \n\
23061 :Parameters:\n\
23062     mechanism : int\n\
23063         key mechanism enumeration constant (CKM_*)\n\
23064     iv : SecItem object\n\
23065         initialization vector. If there is no initialization vector you may also pass\n\
23066         None or an empty SecItem object (e.g. SecItem())\n\
23067 \n\
23068 Return a SecItem to be used as the initialization vector for encryption/decryption.\n\
23069 ");
23070 static PyObject *
pk11_param_from_iv(PyObject * self,PyObject * args,PyObject * kwds)23071 pk11_param_from_iv(PyObject *self, PyObject *args, PyObject *kwds)
23072 {
23073     static char *kwlist[] = {"mechanism", "iv", NULL};
23074     unsigned long mechanism;
23075     SecItem *py_iv;
23076     SECItem *sec_param;
23077 
23078     TraceMethodEnter(self);
23079 
23080     if (!PyArg_ParseTupleAndKeywords(args, kwds, "k|O&:param_from_iv", kwlist,
23081                                      &mechanism, SecItemOrNoneConvert, &py_iv))
23082         return NULL;
23083 
23084     if ((sec_param = PK11_ParamFromIV(mechanism, py_iv ? &py_iv->item : NULL)) == NULL) {
23085         return set_nspr_error(NULL);
23086     }
23087 
23088     // FIXME - SecItem_new_from_SECItem makes a copy, the sec_param should be freed)
23089     return SecItem_new_from_SECItem(sec_param, SECITEM_iv_param);
23090 }
23091 
23092 PyDoc_STRVAR(pk11_param_from_algid_doc,
23093 "param_from_algid(algid) -> SecItem\n\
23094 \n\
23095 :Parameters:\n\
23096     algid : AlgorithmID object\n\
23097         algorithm id\n\
23098 \n\
23099 Return a SecItem containing a encryption param derived from a AlgorithmID.\n\
23100 ");
23101 static PyObject *
pk11_param_from_algid(PyObject * self,PyObject * args)23102 pk11_param_from_algid(PyObject *self, PyObject *args)
23103 {
23104     AlgorithmID *py_algorithm;
23105     SECItem *param;
23106 
23107     TraceMethodEnter(self);
23108 
23109     if (!PyArg_ParseTuple(args, "O!:param_from_algid", &AlgorithmIDType, &py_algorithm))
23110         return NULL;
23111 
23112     if ((param = PK11_ParamFromAlgid(&py_algorithm->id)) == NULL) {
23113         return set_nspr_error(NULL);
23114     }
23115 
23116     return SecItem_new_from_SECItem(param, SECITEM_unknown);
23117 }
23118 
23119 PyDoc_STRVAR(pk11_generate_new_param_doc,
23120 "generate_new_param(mechanism, sym_key=None) -> SecItem\n\
23121 \n\
23122 :Parameters:\n\
23123     mechanism : int\n\
23124         key mechanism enumeration constant (CKM_*)\n\
23125     sym_key : PK11SymKey object or None\n\
23126         symmetric key or None\n\
23127 \n\
23128 Return a SecItem containing a encryption param.\n\
23129 ");
23130 static PyObject *
pk11_generate_new_param(PyObject * self,PyObject * args,PyObject * kwds)23131 pk11_generate_new_param(PyObject *self, PyObject *args, PyObject *kwds)
23132 {
23133     static char *kwlist[] = {"mechanism", "sym_key", NULL};
23134     unsigned long mechanism;
23135     PyPK11SymKey *py_sym_key;
23136     SECItem *param;
23137 
23138     TraceMethodEnter(self);
23139 
23140     if (!PyArg_ParseTupleAndKeywords(args, kwds, "k|O&:generate_new_param", kwlist,
23141                                      &mechanism, SymKeyOrNoneConvert, &py_sym_key))
23142         return NULL;
23143 
23144     if ((param = PK11_GenerateNewParam(mechanism,
23145                                        py_sym_key ? py_sym_key->pk11_sym_key : NULL)) == NULL) {
23146         return set_nspr_error(NULL);
23147     }
23148 
23149     return SecItem_new_from_SECItem(param, SECITEM_unknown);
23150 }
23151 
23152 PyDoc_STRVAR(pk11_algtag_to_mechanism_doc,
23153 "algtag_to_mechanism(algtag) -> mechanism\n\
23154 \n\
23155 :Parameters:\n\
23156     algtag : int\n\
23157         algorithm tag (e.g. SEC_OID_*)\n\
23158 \n\
23159 Returns the key mechanism enumeration constant (CKM_*)\n\
23160 given an algorithm tag. Throws a KeyError exception if the \n\
23161 algorithm tag is invalid.\n\
23162 ");
23163 static PyObject *
pk11_algtag_to_mechanism(PyObject * self,PyObject * args)23164 pk11_algtag_to_mechanism(PyObject *self, PyObject *args)
23165 {
23166     unsigned long algtag;
23167     unsigned long mechanism;
23168 
23169     TraceMethodEnter(self);
23170 
23171     if (!PyArg_ParseTuple(args, "k:algtag_to_mechanism", &algtag))
23172         return NULL;
23173 
23174     if ((mechanism = PK11_AlgtagToMechanism(algtag)) == CKM_INVALID_MECHANISM) {
23175 	PyErr_Format(PyExc_KeyError, "algtag not found: %#lx", algtag);
23176         return NULL;
23177     }
23178 
23179     return PyLong_FromLong(mechanism);
23180 }
23181 
23182 PyDoc_STRVAR(pk11_mechanism_to_algtag_doc,
23183 "mechanism_to_algtag(mechanism) -> algtag\n\
23184 \n\
23185 :Parameters:\n\
23186     mechanism : int\n\
23187         key mechanism enumeration constant (CKM_*)\n\
23188 \n\
23189 Returns the algtag given key mechanism enumeration constant (CKM_*)\n\
23190 Throws an KeyError exception if the mechanism is invalid.\n\
23191 ");
23192 static PyObject *
pk11_mechanism_to_algtag(PyObject * self,PyObject * args)23193 pk11_mechanism_to_algtag(PyObject *self, PyObject *args)
23194 {
23195     unsigned long algtag;
23196     unsigned long mechanism;
23197 
23198     TraceMethodEnter(self);
23199 
23200     if (!PyArg_ParseTuple(args, "k:mechanism_to_algtag", &mechanism))
23201         return NULL;
23202 
23203     if ((algtag = PK11_MechanismToAlgtag(mechanism)) == SEC_OID_UNKNOWN) {
23204 	PyErr_Format(PyExc_KeyError, "mechanism not found: %#lx", mechanism);
23205         return NULL;
23206     }
23207 
23208     return PyLong_FromLong(algtag);
23209 }
23210 PyDoc_STRVAR(pk11_get_iv_length_doc,
23211 "get_iv_length(mechanism) -> algtag\n\
23212 \n\
23213 :Parameters:\n\
23214     mechanism : int\n\
23215         key mechanism enumeration constant (CKM_*)\n\
23216 \n\
23217 Returns the length of the mechanism's initialization vector.\n\
23218 ");
23219 static PyObject *
pk11_get_iv_length(PyObject * self,PyObject * args)23220 pk11_get_iv_length(PyObject *self, PyObject *args)
23221 {
23222     unsigned long mechanism;
23223     int iv_length;
23224 
23225     TraceMethodEnter(self);
23226 
23227     if (!PyArg_ParseTuple(args, "k:get_iv_length", &mechanism))
23228         return NULL;
23229 
23230     iv_length = PK11_GetIVLength(mechanism);
23231 
23232     return PyLong_FromLong(iv_length);
23233 }
23234 
23235 PyDoc_STRVAR(pk11_get_block_size_doc,
23236 "get_block_size(mechanism, sec_param=None) -> int\n\
23237 \n\
23238 :Parameters:\n\
23239     mechanism : int\n\
23240         key mechanism enumeration constant (CKM_*)\n\
23241     sec_param : SecItem object or None\n\
23242         mechanism parameters used to build this context or None.\n\
23243 \n\
23244 Get the mechanism block size\n\
23245 ");
23246 static PyObject *
pk11_get_block_size(PyObject * self,PyObject * args,PyObject * kwds)23247 pk11_get_block_size(PyObject *self, PyObject *args, PyObject *kwds)
23248 {
23249     static char *kwlist[] = {"mechanism", "sec_param", NULL};
23250     unsigned long mechanism;
23251     SecItem *py_sec_param;
23252     int block_size;
23253 
23254     TraceMethodEnter(self);
23255 
23256     if (!PyArg_ParseTupleAndKeywords(args, kwds, "k|O&:get_block_size", kwlist,
23257                                      &mechanism, SecItemOrNoneConvert, &py_sec_param))
23258         return NULL;
23259 
23260     block_size = PK11_GetBlockSize(mechanism, py_sec_param ? &py_sec_param->item : NULL);
23261 
23262     return PyLong_FromLong(block_size);
23263 }
23264 
23265 PyDoc_STRVAR(pk11_get_pad_mechanism_doc,
23266 "get_pad_mechanism(mechanism) -> int\n\
23267 \n\
23268 :Parameters:\n\
23269     mechanism : int\n\
23270         key mechanism enumeration constant (CKM_*)\n\
23271 \n\
23272 Determine appropriate mechanism to use when padding is required.\n\
23273 If the mechanism does not map to a padding mechanism return the mechanism.\n\
23274 ");
23275 static PyObject *
pk11_get_pad_mechanism(PyObject * self,PyObject * args)23276 pk11_get_pad_mechanism(PyObject *self, PyObject *args)
23277 {
23278     unsigned long mechanism;
23279     unsigned long pad_mechanism;
23280 
23281     TraceMethodEnter(self);
23282 
23283     if (!PyArg_ParseTuple(args, "k:get_pad_mechanism", &mechanism))
23284         return NULL;
23285 
23286     pad_mechanism = PK11_GetPadMechanism(mechanism);
23287 
23288     return PyLong_FromLong(pad_mechanism);
23289 }
23290 
23291 PyDoc_STRVAR(pk11_import_crl_doc,
23292 "import_crl(slot, der_crl, url, type, import_options, decode_options, [user_data1, ...]) -> SignedCRL\n\
23293 \n\
23294 :Parameters:\n\
23295     slot : PK11Slot object\n\
23296         designated PK11 slot\n\
23297     der_crl : SecItem object\n\
23298         signed DER CRL data encapsulated in a SecItem object.\n\
23299     url : string\n\
23300         URL of the CRL\n\
23301     type : int\n\
23302         revocation list type\n\
23303         \n\
23304         may be one of:\n\
23305           - SEC_CRL_TYPE\n\
23306           - SEC_KRL_TYPE\n\
23307         \n\
23308     import_options : int\n\
23309         bit-wise OR of the following flags:\n\
23310           - CRL_IMPORT_BYPASS_CHECKS\n\
23311         \n\
23312         or use CRL_IMPORT_DEFAULT_OPTIONS\n\
23313     decode_options : int\n\
23314         bit-wise OR of the following flags:\n\
23315           - CRL_DECODE_DONT_COPY_DER\n\
23316           - CRL_DECODE_SKIP_ENTRIES\n\
23317           - CRL_DECODE_KEEP_BAD_CRL\n\
23318           - CRL_DECODE_ADOPT_HEAP_DER\n\
23319         \n\
23320         or use CRL_DECODE_DEFAULT_OPTIONS\n\
23321     user_dataN : object\n\
23322         zero or more caller supplied parameters which will\n\
23323         be passed to the password callback function\n\
23324 \n\
23325 \n\
23326 ");
23327 static PyObject *
pk11_import_crl(PyObject * self,PyObject * args)23328 pk11_import_crl(PyObject *self, PyObject *args)
23329 {
23330     Py_ssize_t n_base_args = 6;
23331     Py_ssize_t argc;
23332     PyObject *parse_args = NULL;
23333     PyObject *pin_args = NULL;
23334     PK11Slot *py_slot;
23335     char *url;
23336     int type;
23337     int import_options;
23338     int decode_options;
23339     SecItem *py_der_signed_crl;
23340     CERTSignedCrl *signed_crl;
23341 
23342     TraceMethodEnter(self);
23343 
23344     argc = PyTuple_Size(args);
23345     if (argc == n_base_args) {
23346         Py_INCREF(args);
23347         parse_args = args;
23348     } else {
23349         parse_args = PyTuple_GetSlice(args, 0, n_base_args);
23350     }
23351 
23352     if (!PyArg_ParseTuple(parse_args, "O!O!siii:import_crl",
23353                           &PK11SlotType, &py_slot,
23354                           &SecItemType, &py_der_signed_crl,
23355                           &url, &type, &import_options, &decode_options)) {
23356         Py_DECREF(parse_args);
23357         return NULL;
23358     }
23359     Py_DECREF(parse_args);
23360 
23361     pin_args = PyTuple_GetSlice(args, n_base_args, argc);
23362 
23363     Py_BEGIN_ALLOW_THREADS
23364     if ((signed_crl = PK11_ImportCRL(py_slot->slot, &py_der_signed_crl->item, url,
23365                                      type, pin_args, import_options, NULL, decode_options)) == NULL) {
23366 	Py_BLOCK_THREADS
23367         Py_DECREF(pin_args);
23368         return set_nspr_error(NULL);
23369     }
23370     Py_END_ALLOW_THREADS
23371 
23372     Py_DECREF(pin_args);
23373 
23374     return SignedCRL_new_from_CERTSignedCRL(signed_crl);
23375 }
23376 
23377 PyDoc_STRVAR(pk11_create_pbev2_algorithm_id_doc,
23378 "create_pbev2_algorithm_id(pbe_alg=SEC_OID_PKCS5_PBKDF2, cipher_alg=SEC_OID_AES_256_CBC, prf_alg=SEC_OID_HMAC_SHA1, key_length=0, iterations=100, salt=None) -> AlgorithmID \n\
23379 \n\
23380 :Parameters:\n\
23381     pbe_alg : may be one of integer, string or SecItem (see below)\n\
23382         password based encryption algorithm\n\
23383     cipher_alg : may be one of integer, string or SecItem (see below)\n\
23384         cipher algorithm\n\
23385     prf_alg : may be one of integer, string or SecItem (see below)\n\
23386         pseudo-random function algorithm\n\
23387     key_length : int\n\
23388         Number of octets in derived key DK. Must be a valid value for the\n\
23389         cipher_alg. If zero then NSS will select the longest key length\n\
23390         appropriate for the cipher\n\
23391     iterations : int\n\
23392         Number of times the pseudo-random function is applied to generate\n\
23393         the symmetric key.\n\
23394     salt : SecItem or str or any buffer compatible object or None\n\
23395         Cyrptographic salt. If None a random salt will be generated.\n\
23396 \n\
23397 The default values are appropriate for most users desiring a PKCS5v2\n\
23398 PBE symmetric key.\n\
23399 \n\
23400 The pbe, cipher and prf algorithms may be specified in any of the\n\
23401 following manners:\n\
23402 \n\
23403     * integer:: A SEC OID enumeration constant, also known as a tag\n\
23404       (i.e. SEC_OID_*) for example SEC_OID_PKCS5_PBKDF2.\n\
23405     * string:: A string for the tag name\n\
23406       (e.g. 'SEC_OID_PKCS5_PBKDF2') The 'SEC_OID\\_' prefix is\n\
23407       optional. A string in dotted decimal representation, for\n\
23408       example 'OID.1.2.840.113549.1.5.12'.\n\
23409       The 'OID.' prefix is optional. Case is not significant.\n\
23410     * SecItem:: A SecItem object encapsulating the OID in \n\
23411           DER format.\n\
23412 \n\
23413 ");
23414 
23415 static PyObject *
pk11_create_pbev2_algorithm_id(PyObject * self,PyObject * args,PyObject * kwds)23416 pk11_create_pbev2_algorithm_id(PyObject *self, PyObject *args, PyObject *kwds)
23417 {
23418     static char *kwlist[] = {"pbe_alg", "cipher_alg", "prf_alg",
23419                              "key_length", "iterations", "salt", NULL};
23420     PyObject *py_pbe_alg = NULL;
23421     SECOidTag pbe_alg_tag = SEC_OID_PKCS5_PBKDF2;
23422 
23423     PyObject *py_cipher_alg = NULL;
23424     SECOidTag cipher_alg_tag = SEC_OID_AES_256_CBC;
23425 
23426     PyObject *py_prf_alg = NULL;
23427     SECOidTag prf_alg_tag = SEC_OID_HMAC_SHA1;
23428 
23429     int key_length = 0;
23430     int iterations = 100;
23431 
23432     SECItem_param *salt_param = NULL;
23433 
23434     SECAlgorithmID *algid = NULL;
23435     PyObject *py_algorithm_id = NULL;
23436 
23437     TraceMethodEnter(self);
23438 
23439     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOOiiO&:create_pbev2_algorithm_id", kwlist,
23440                                      &py_pbe_alg, &py_cipher_alg, &py_prf_alg,
23441                                      &key_length, &iterations,
23442                                      SECItemOrNoneConvert, &salt_param))
23443         return NULL;
23444 
23445     if (py_pbe_alg) {
23446         if ((pbe_alg_tag = get_oid_tag_from_object(py_pbe_alg)) == -1) {
23447             SECItem_param_release(salt_param);
23448             return NULL;
23449         }
23450     }
23451 
23452     if (py_cipher_alg) {
23453         if ((cipher_alg_tag = get_oid_tag_from_object(py_cipher_alg)) == -1) {
23454             SECItem_param_release(salt_param);
23455             return NULL;
23456         }
23457     }
23458 
23459     if (py_prf_alg) {
23460         if ((prf_alg_tag = get_oid_tag_from_object(py_prf_alg)) == -1) {
23461             SECItem_param_release(salt_param);
23462             return NULL;
23463         }
23464     }
23465 
23466     if ((algid = PK11_CreatePBEV2AlgorithmID(pbe_alg_tag,
23467                                              cipher_alg_tag,
23468                                              prf_alg_tag,
23469                                              key_length,
23470                                              iterations,
23471                                              &salt_param->item)) == NULL) {
23472         SECItem_param_release(salt_param);
23473         return set_nspr_error(NULL);
23474     }
23475 
23476     if ((py_algorithm_id = AlgorithmID_new_from_SECAlgorithmID(algid)) == NULL) {
23477         SECItem_param_release(salt_param);
23478         SECOID_DestroyAlgorithmID(algid, PR_TRUE);
23479         return NULL;
23480     }
23481     SECItem_param_release(salt_param);
23482     SECOID_DestroyAlgorithmID(algid, PR_TRUE);
23483     return py_algorithm_id;
23484 }
23485 
23486 PyDoc_STRVAR(cert_decode_der_crl_doc,
23487 "decode_der_crl(der_crl, type=SEC_CRL_TYPE, decode_options=CRL_DECODE_DEFAULT_OPTIONS) -> SignedCRL\n\
23488 \n\
23489 :Parameters:\n\
23490     der_crl : SecItem object\n\
23491         DER encoded CRL data encapsulated in a SECItem.\n\
23492     type : int\n\
23493         revocation list type\n\
23494         \n\
23495         may be one of:\n\
23496           - SEC_CRL_TYPE\n\
23497           - SEC_KRL_TYPE\n\
23498     decode_options : int\n\
23499         bit-wise OR of the following flags:\n\
23500           - CRL_DECODE_DONT_COPY_DER\n\
23501           - CRL_DECODE_SKIP_ENTRIES\n\
23502           - CRL_DECODE_KEEP_BAD_CRL\n\
23503           - CRL_DECODE_ADOPT_HEAP_DER\n\
23504         \n\
23505         or use CRL_DECODE_DEFAULT_OPTIONS\n\
23506 \n\
23507 ");
23508 
23509 static PyObject *
cert_decode_der_crl(PyObject * self,PyObject * args,PyObject * kwds)23510 cert_decode_der_crl(PyObject *self, PyObject *args, PyObject *kwds)
23511 {
23512     static char *kwlist[] = {"der_crl", "type", "decode_options", NULL};
23513     SecItem *py_der_crl;
23514     int type = SEC_CRL_TYPE;
23515     int decode_options = CRL_DECODE_DEFAULT_OPTIONS;
23516     CERTSignedCrl *signed_crl;
23517 
23518     TraceMethodEnter(self);
23519 
23520     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|ii:decode_der_crl", kwlist,
23521                                      &SecItemType, &py_der_crl,
23522                                      &py_der_crl, &type, &decode_options))
23523         return NULL;
23524 
23525     if ((signed_crl = CERT_DecodeDERCrlWithFlags(NULL, &py_der_crl->item, type,  decode_options)) == NULL) {
23526         return set_nspr_error(NULL);
23527     }
23528 
23529     return SignedCRL_new_from_CERTSignedCRL(signed_crl);
23530 }
23531 
23532 PyDoc_STRVAR(nss_read_der_from_file_doc,
23533 "read_der_from_file(file, ascii=False) -> SecItem\n\
23534 \n\
23535 :Parameters:\n\
23536     file : file name or file object\n\
23537         If string treat as file path to open and read,\n\
23538         if file object read from file object.\n\
23539     ascii : bool\n\
23540         If True treat file contents as ascii data.\n\
23541         If PEM delimiters are found strip them.\n\
23542         Then base64 decode the contents.\n\
23543 \n\
23544 Read the contents of a file and return as a SecItem object.\n\
23545 If file is a string then treat it as a file pathname and open\n\
23546 and read the contents of that file. If file is a file object\n\
23547 then read the contents from the file object\n\
23548 \n\
23549 If the file contents begin with a PEM header then treat the\n\
23550 the file as PEM encoded and decode the payload into DER form.\n\
23551 Otherwise the file contents is assumed to already be in DER form.\n\
23552 The returned SecItem contains the DER contents of the file.\n\
23553 ");
23554 
23555 static PyObject *
nss_read_der_from_file(PyObject * self,PyObject * args,PyObject * kwds)23556 nss_read_der_from_file(PyObject *self, PyObject *args, PyObject *kwds)
23557 {
23558     static char *kwlist[] = {"file", "ascii", NULL};
23559     PyObject *file_arg;
23560     int ascii = 0;
23561     PyObject *py_sec_item;
23562     PyObject *py_file_contents;
23563 
23564     TraceMethodEnter(self);
23565 
23566     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|i:read_der_from_file", kwlist,
23567                                      &file_arg, &ascii))
23568         return NULL;
23569 
23570     if ((py_file_contents = read_data_from_file(file_arg, "rb")) == NULL) {
23571         goto fail;
23572     }
23573 
23574     if (!PyBytes_Check(py_file_contents)) {
23575         PyErr_Format(PyExc_TypeError, "expected file contents to be bytes, not %.200s",
23576                      Py_TYPE(py_file_contents)->tp_name);
23577 
23578         goto fail;
23579     }
23580 
23581     if (ascii) {
23582         if ((py_sec_item = base64_to_SecItem(PyBytes_AsString(py_file_contents))) == NULL) {
23583             goto fail;
23584         }
23585     } else {
23586         SECItem der;
23587 
23588         der.data = (unsigned char *)PyBytes_AsString(py_file_contents);
23589         der.len = PyBytes_GET_SIZE(py_file_contents);
23590         der.type = siBuffer;
23591 
23592         if ((py_sec_item = SecItem_new_from_SECItem(&der, SECITEM_unknown)) == NULL) {
23593             goto fail;
23594         }
23595     }
23596 
23597     Py_DECREF(py_file_contents);
23598     return (PyObject *)py_sec_item;
23599 
23600  fail:
23601     Py_XDECREF(py_file_contents);
23602     return NULL;
23603 }
23604 
23605 PyDoc_STRVAR(nss_base64_to_binary_doc,
23606 "base64_to_binary(text) -> SecItem\n\
23607 \n\
23608 :Parameters:\n\
23609     text : string\n\
23610         string containing base64 data.\n\
23611 \n\
23612 Convert the base64 encoded data to binary data.\n\
23613 \n\
23614 The text is assumed to contain base64 text. The base64 text may\n\
23615 optionally be wrapped in a PEM header and footer.\n\
23616 \n\
23617 Returns a SecItem containg the binary data.\n\
23618 \n\
23619 Note, a SecItem can be initialized directly from base64 text by\n\
23620 utilizing the ascii parameter to the SecItem constructor, thus\n\
23621 the two are equivalent:\n\
23622 \n\
23623     sec_item = nss.base64_to_binary(text)\n\
23624     sec_tiem = nss.SecItem(text, ascii=True)\n\
23625 \n\
23626 ");
23627 
23628 static PyObject *
nss_base64_to_binary(PyObject * self,PyObject * args,PyObject * kwds)23629 nss_base64_to_binary(PyObject *self, PyObject *args, PyObject *kwds)
23630 {
23631     static char *kwlist[] = {"text", NULL};
23632     char *text = NULL;
23633 
23634     TraceMethodEnter(self);
23635 
23636     if (!PyArg_ParseTupleAndKeywords(args, kwds, "s:base64_to_binary", kwlist,
23637                                      &text))
23638         return NULL;
23639 
23640     return base64_to_SecItem(text);
23641 }
23642 
23643 PyDoc_STRVAR(cert_x509_key_usage_doc,
23644 "x509_key_usage(bitstr, repr_kind=AsEnumDescription) -> (str, ...)\n\
23645 \n\
23646 :Parameters:\n\
23647     bitstr : SecItem object\n\
23648         A SecItem containing a DER encoded bit string.\n\
23649     repr_kind : RepresentationKind constant\n\
23650         Specifies what the contents of the returned tuple will be.\n\
23651         May be one of:\n\
23652 \n\
23653         AsEnum\n\
23654             The enumerated constant.\n\
23655             (e.g. nss.KU_DIGITAL_SIGNATURE)\n\
23656         AsEnumDescription\n\
23657             A friendly human readable description of the enumerated constant as a string.\n\
23658              (e.g. \"Digital Signature\")\n\
23659         AsIndex\n\
23660             The bit position within the bit string.\n\
23661 \n\
23662 Return a tuple of string name for each enabled bit in the key\n\
23663 usage bit string.\n\
23664 ");
23665 
23666 static PyObject *
cert_x509_key_usage(PyObject * self,PyObject * args,PyObject * kwds)23667 cert_x509_key_usage(PyObject *self, PyObject *args, PyObject *kwds)
23668 {
23669     static char *kwlist[] = {"bitstr", "repr_kind", NULL};
23670     PyObject *result;
23671     SecItem *py_sec_item;
23672     SECItem bitstr_item;
23673     int repr_kind = AsEnumDescription;
23674 
23675     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|i:x509_key_usage", kwlist,
23676                                      &SecItemType, &py_sec_item, &repr_kind))
23677         return NULL;
23678 
23679     if (der_bitstring_to_nss_bitstring(&bitstr_item, &py_sec_item->item) != SECSuccess) {
23680         return set_nspr_error(NULL);
23681     }
23682 
23683     result = key_usage_bitstr_to_tuple(&bitstr_item, repr_kind);
23684 
23685     return result;
23686 }
23687 
23688 PyDoc_STRVAR(cert_x509_cert_type_doc,
23689 "x509_cert_type(bitstr, repr_kind=AsEnumDescription) -> (str, ...)\n\
23690 \n\
23691 :Parameters:\n\
23692     bitstr : SecItem object\n\
23693         A SecItem containing a DER encoded bit string.\n\
23694     repr_kind : RepresentationKind constant\n\
23695         Specifies what the contents of the returned tuple will be.\n\
23696         May be one of:\n\
23697 \n\
23698         AsEnum\n\
23699             The enumerated constant.\n\
23700             (e.g. nss.NS_CERT_TYPE_SSL_SERVER)\n\
23701         AsEnumDescription\n\
23702             A friendly human readable description of the enumerated constant as a string.\n\
23703              (e.g. \"SSL Server\")\n\
23704         AsIndex\n\
23705             The bit position within the bit string.\n\
23706 \n\
23707 Return a tuple of string name for each enabled bit in the key\n\
23708 usage bit string.\n\
23709 ");
23710 
23711 static PyObject *
cert_x509_cert_type(PyObject * self,PyObject * args,PyObject * kwds)23712 cert_x509_cert_type(PyObject *self, PyObject *args, PyObject *kwds)
23713 {
23714     static char *kwlist[] = {"bitstr", "repr_kind", NULL};
23715     PyObject *result;
23716     SecItem *py_sec_item;
23717     SECItem bitstr_item;
23718     int repr_kind = AsEnumDescription;
23719 
23720     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|i:x509_cert_type", kwlist,
23721                                      &SecItemType, &py_sec_item, &repr_kind))
23722         return NULL;
23723 
23724     if (der_bitstring_to_nss_bitstring(&bitstr_item, &py_sec_item->item) != SECSuccess) {
23725         return set_nspr_error(NULL);
23726     }
23727 
23728     result = cert_type_bitstr_to_tuple(&bitstr_item, repr_kind);
23729 
23730     return result;
23731 }
23732 
23733 PyDoc_STRVAR(cert_x509_ext_key_usage_doc,
23734 "x509_ext_key_usage(sec_item, repr_kind=AsString) -> (obj, ...)\n\
23735 \n\
23736 :Parameters:\n\
23737     sec_item : SecItem object\n\
23738         A SecItem containing a DER encoded sequence of OID's\n\
23739     repr_kind : RepresentationKind constant\n\
23740         Specifies what the contents of the returned tuple will be.\n\
23741         May be one of:\n\
23742 \n\
23743         AsObject\n\
23744             Each extended key usage will be a SecItem object embedding\n\
23745             the OID in DER format.\n\
23746         AsString\n\
23747             Each extended key usage will be a descriptive string.\n\
23748             (e.g. \"TLS Web Server Authentication Certificate\")\n\
23749         AsDottedDecimal\n\
23750             Each extended key usage will be OID rendered as a dotted decimal string.\n\
23751             (e.g. \"OID.1.3.6.1.5.5.7.3.1\")\n\
23752         AsEnum\n\
23753             Each extended key usage will be OID tag enumeration constant (int).\n\
23754             (e.g. nss.SEC_OID_EXT_KEY_USAGE_SERVER_AUTH)\n\
23755 \n\
23756 Return a tuple of OID's according the representation kind.\n\
23757 ");
23758 
23759 static PyObject *
cert_x509_ext_key_usage(PyObject * self,PyObject * args,PyObject * kwds)23760 cert_x509_ext_key_usage(PyObject *self, PyObject *args, PyObject *kwds)
23761 {
23762     static char *kwlist[] = {"sec_item", "repr_kind", NULL};
23763     SecItem *py_sec_item;
23764     int repr_kind = AsString;
23765 
23766     if (!PyArg_ParseTupleAndKeywords(args, kwds,"O!|i:x509_ext_key_usage", kwlist,
23767                           &SecItemType, &py_sec_item, &repr_kind))
23768         return NULL;
23769 
23770     return decode_oid_sequence_to_tuple(&py_sec_item->item, repr_kind);
23771 }
23772 
23773 
23774 PyDoc_STRVAR(cert_x509_alt_name_doc,
23775 "x509_alt_name(sec_item, repr_kind=AsString) -> (SecItem, ...)\n\
23776 \n\
23777 :Parameters:\n\
23778     sec_item : SecItem object\n\
23779         A SecItem containing a DER encoded alternative name extension.\n\
23780     repr_kind : RepresentationKind constant\n\
23781         Specifies what the contents of the returned tuple will be.\n\
23782         May be one of:\n\
23783 \n\
23784         AsObject\n\
23785             The general name as a nss.GeneralName object\n\
23786         AsString\n\
23787             The general name as a string.\n\
23788             (e.g. \"http://crl.geotrust.com/crls/secureca.crl\")\n\
23789         AsTypeString\n\
23790             The general name type as a string.\n\
23791              (e.g. \"URI\")\n\
23792         AsTypeEnum\n\
23793             The general name type as a general name type enumerated constant.\n\
23794              (e.g. nss.certURI )\n\
23795         AsLabeledString\n\
23796             The general name as a string with it's type prepended.\n\
23797             (e.g. \"URI: http://crl.geotrust.com/crls/secureca.crl\"\n\
23798 \n\
23799 Return a tuple of GeneralNames according the representation kind.\n\
23800 ");
23801 
23802 static PyObject *
cert_x509_alt_name(PyObject * self,PyObject * args,PyObject * kwds)23803 cert_x509_alt_name(PyObject *self, PyObject *args, PyObject *kwds)
23804 {
23805     static char *kwlist[] = {"sec_item", "repr_kind", NULL};
23806     SecItem *py_sec_item;
23807     int repr_kind = AsString;
23808     CERTGeneralName *names;
23809     PLArenaPool *arena;
23810     PyObject *result;
23811 
23812 
23813     if (!PyArg_ParseTupleAndKeywords(args, kwds,"O!|i:x509_alt_name", kwlist,
23814                           &SecItemType, &py_sec_item, &repr_kind))
23815         return NULL;
23816 
23817     if ((arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE)) == NULL ) {
23818         return set_nspr_error(NULL);
23819     }
23820 
23821     if ((names = CERT_DecodeAltNameExtension(arena, &py_sec_item->item)) == NULL) {
23822         set_nspr_error(NULL);
23823         PORT_FreeArena(arena, PR_FALSE);
23824         return NULL;
23825     }
23826 
23827     result = CERTGeneralName_list_to_tuple(names, repr_kind);
23828     PORT_FreeArena(arena, PR_FALSE);
23829     return result;
23830 }
23831 
23832 
23833 static PyObject *
crl_reason_to_pystr(CERTCRLEntryReasonCode reason)23834 crl_reason_to_pystr(CERTCRLEntryReasonCode reason)
23835 {
23836     PyObject *py_value;
23837     PyObject *py_name;
23838 
23839     if ((py_value = PyLong_FromLong(reason)) == NULL) {
23840         PyErr_SetString(PyExc_MemoryError, "unable to create object");
23841         return NULL;
23842     }
23843 
23844     if ((py_name = PyDict_GetItem(crl_reason_value_to_name, py_value)) == NULL) {
23845         Py_DECREF(py_value);
23846 	PyErr_Format(PyExc_KeyError, "CRL reason name not found: %u", reason);
23847         return NULL;
23848     }
23849 
23850     Py_DECREF(py_value);
23851     Py_INCREF(py_name);
23852 
23853     return py_name;
23854 }
23855 
23856 PyDoc_STRVAR(cert_crl_reason_name_doc,
23857 "crl_reason_name(reason) -> string\n\
23858 \n\
23859 :Parameters:\n\
23860     reason : int\n\
23861         CERTCRLEntryReasonCode constant\n\
23862 \n\
23863 Given a CERTCRLEntryReasonCode constant\n\
23864 return it's name as a string\n\
23865 ");
23866 static PyObject *
cert_crl_reason_name(PyObject * self,PyObject * args)23867 cert_crl_reason_name(PyObject *self, PyObject *args)
23868 {
23869     unsigned long reason;
23870 
23871     TraceMethodEnter(self);
23872 
23873     if (!PyArg_ParseTuple(args, "k:crl_reason_name", &reason))
23874         return NULL;
23875 
23876     return crl_reason_to_pystr(reason);
23877 }
23878 
23879 PyDoc_STRVAR(cert_crl_reason_from_name_doc,
23880 "crl_reason_from_name(name) -> int\n\
23881 \n\
23882 :Parameters:\n\
23883     name : string\n\
23884         name of CERTCRLEntryReasonCode constant\n\
23885 \n\
23886 Given the name of a CERTCRLEntryReasonCode constant\n\
23887 return it's integer constant\n\
23888 The string comparison is case insensitive and will match with\n\
23889 or without the crlEntry prefix\n\
23890 ");
23891 static PyObject *
cert_crl_reason_from_name(PyObject * self,PyObject * args)23892 cert_crl_reason_from_name(PyObject *self, PyObject *args)
23893 {
23894     PyObject *py_name;
23895     PyObject *py_lower_name;
23896     PyObject *py_value;
23897 
23898     TraceMethodEnter(self);
23899 
23900     if (!PyArg_ParseTuple(args, "S:crl_reason_from_name", &py_name))
23901         return NULL;
23902 
23903     if ((py_lower_name = PyUnicode_Lower(py_name)) == NULL) {
23904         return NULL;
23905     }
23906 
23907     if ((py_value = PyDict_GetItem(crl_reason_name_to_value, py_lower_name)) == NULL) {
23908         PyObject *py_name_utf8 = PyBaseString_UTF8(py_name, "reason name");
23909 	PyErr_Format(PyExc_KeyError, "CRL reason name not found: %s", PyBytes_AsString(py_name_utf8));
23910         Py_DECREF(py_lower_name);
23911         Py_XDECREF(py_name_utf8);
23912         return NULL;
23913     }
23914 
23915     Py_DECREF(py_lower_name);
23916     Py_INCREF(py_value);
23917 
23918     return py_value;
23919 }
23920 
23921 static PyObject *
pkcs12_cipher_to_pystr(long cipher)23922 pkcs12_cipher_to_pystr(long cipher)
23923 {
23924     PyObject *py_value;
23925     PyObject *py_name;
23926 
23927     if ((py_value = PyLong_FromLong(cipher)) == NULL) {
23928         PyErr_SetString(PyExc_MemoryError, "unable to create object");
23929         return NULL;
23930     }
23931 
23932     if ((py_name = PyDict_GetItem(pkcs12_cipher_value_to_name, py_value)) == NULL) {
23933         Py_DECREF(py_value);
23934 	PyErr_Format(PyExc_KeyError, "PKCS12 cipher name not found: %ld", cipher);
23935         return NULL;
23936     }
23937 
23938     Py_DECREF(py_value);
23939     Py_INCREF(py_name);
23940 
23941     return py_name;
23942 }
23943 
23944 PyDoc_STRVAR(pkcs12_cipher_name_doc,
23945 "pkcs12_cipher_name(cipher) -> string\n\
23946 \n\
23947 :Parameters:\n\
23948     cipher : int\n\
23949         PKCS12_* constant\n\
23950 \n\
23951 Given a PKCS12_* constant\n\
23952 return it's name as a string\n\
23953 ");
23954 static PyObject *
pkcs12_cipher_name(PyObject * self,PyObject * args)23955 pkcs12_cipher_name(PyObject *self, PyObject *args)
23956 {
23957     unsigned long cipher;
23958 
23959     TraceMethodEnter(self);
23960 
23961     if (!PyArg_ParseTuple(args, "k:pkcs12_cipher_name", &cipher))
23962         return NULL;
23963 
23964     return pkcs12_cipher_to_pystr(cipher);
23965 }
23966 
23967 PyDoc_STRVAR(pkcs12_cipher_from_name_doc,
23968 "pkcs12_cipher_from_name(name) -> int\n\
23969 \n\
23970 :Parameters:\n\
23971     name : string\n\
23972         name of PKCS12_* constant\n\
23973 \n\
23974 Given the name of a PKCS12_* constant\n\
23975 return it's integer constant\n\
23976 The string comparison is case insensitive and will match with\n\
23977 or without the PKCS12\\_ prefix\n\
23978 ");
23979 static PyObject *
pkcs12_cipher_from_name(PyObject * self,PyObject * args)23980 pkcs12_cipher_from_name(PyObject *self, PyObject *args)
23981 {
23982     PyObject *py_name;
23983     PyObject *py_lower_name;
23984     PyObject *py_value;
23985 
23986     TraceMethodEnter(self);
23987 
23988     if (!PyArg_ParseTuple(args, "S:pkcs12_cipher_from_name", &py_name))
23989         return NULL;
23990 
23991     if ((py_lower_name = PyUnicode_Lower(py_name)) == NULL) {
23992         return NULL;
23993     }
23994 
23995     if ((py_value = PyDict_GetItem(pkcs12_cipher_name_to_value, py_lower_name)) == NULL) {
23996         PyObject *py_name_utf8 = PyBaseString_UTF8(py_name, "cipher name");
23997 	PyErr_Format(PyExc_KeyError, "PKCS12 cipher name not found: %s", PyBytes_AsString(py_name_utf8));
23998         Py_DECREF(py_lower_name);
23999         Py_XDECREF(py_name_utf8);
24000         return NULL;
24001     }
24002 
24003     Py_DECREF(py_lower_name);
24004     Py_INCREF(py_value);
24005 
24006     return py_value;
24007 }
24008 
24009 PyDoc_STRVAR(pkcs12_map_cipher_doc,
24010 "pkcs12_map_cipher(cipher, key_length=0) -> int\n\
24011 \n\
24012 :Parameters:\n\
24013     cipher : may be one of integer, string or SecItem\n\
24014         May be one of:\n\
24015 \n\
24016         * integer:: A SEC OID enumeration constant, also known as a tag\n\
24017           (i.e. SEC_OID_*) for example SEC_OID_DES_EDE3_CBC.\n\
24018         * string:: A string for the tag name\n\
24019           (e.g. 'SEC_OID_DES_EDE3_CBC') The 'SEC_OID\\_' prefix is\n\
24020           optional. A string in dotted decimal representation, for\n\
24021           example 'OID.2.5.4.3'. The 'OID.' prefix is optional.  Case\n\
24022           is not significant.\n\
24023         * SecItem:: A SecItem object encapsulating the OID in \n\
24024           DER format.\n\
24025     key_length : int\n\
24026         The number of bits in the key. If zero a default will be selected.\n\
24027 \n\
24028 Given an cipher and optionally a key length, map that to a PKCS12 encryption\n\
24029 method returned as a SEC_OID tag.\n\
24030 ");
24031 static PyObject *
pkcs12_map_cipher(PyObject * self,PyObject * args,PyObject * kwds)24032 pkcs12_map_cipher(PyObject *self, PyObject *args, PyObject *kwds)
24033 {
24034     static char *kwlist[] = {"cipher", "key_length", NULL};
24035     PyObject *py_cipher;
24036     int key_length;
24037     int tag;
24038     SECOidTag cipher_tag = SEC_OID_UNKNOWN;
24039 
24040     TraceMethodEnter(self);
24041 
24042     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|i:pkcs12_map_cipher", kwlist,
24043                                      &py_cipher, &key_length))
24044         return NULL;
24045 
24046     if ((tag = get_oid_tag_from_object(py_cipher)) == -1) {
24047         return NULL;
24048     }
24049 
24050     if (!SEC_PKCS5IsAlgorithmPBEAlgTag(tag)) {
24051         cipher_tag = SEC_PKCS5GetPBEAlgorithm(tag, key_length);
24052         /* no eqivalent PKCS5/PKCS12 cipher, use the raw
24053          * encryption tag we got and pass it directly in,
24054          * pkcs12 will use the pkcsv5 mechanism */
24055         if (cipher_tag == SEC_OID_PKCS5_PBES2) {
24056             cipher_tag = tag;
24057         } else if (cipher_tag == SEC_OID_PKCS5_PBMAC1) {
24058             /* make sure we do not have MAC'ing ciphers here */
24059             cipher_tag = SEC_OID_UNKNOWN;
24060         }
24061     } else {
24062         cipher_tag = tag;
24063     }
24064 
24065     return PyLong_FromLong(cipher_tag);
24066 }
24067 
24068 static PyObject *
general_name_type_to_pystr(CERTGeneralNameType type)24069 general_name_type_to_pystr(CERTGeneralNameType type)
24070 {
24071     PyObject *py_value;
24072     PyObject *py_name;
24073 
24074     if ((py_value = PyLong_FromLong(type)) == NULL) {
24075         PyErr_SetString(PyExc_MemoryError, "unable to create object");
24076         return NULL;
24077     }
24078 
24079     if ((py_name = PyDict_GetItem(general_name_value_to_name, py_value)) == NULL) {
24080         Py_DECREF(py_value);
24081 	PyErr_Format(PyExc_KeyError, "GeneralName type name not found: %u", type);
24082         return NULL;
24083     }
24084 
24085     Py_DECREF(py_value);
24086     Py_INCREF(py_name);
24087 
24088     return py_name;
24089 }
24090 
24091 PyDoc_STRVAR(cert_general_name_type_name_doc,
24092 "general_name_type_name(type) -> string\n\
24093 \n\
24094 :Parameters:\n\
24095     type : int\n\
24096         CERTGeneralNameType constant\n\
24097 \n\
24098 Given a CERTGeneralNameType constant\n\
24099 return it's name as a string\n\
24100 ");
24101 static PyObject *
cert_general_name_type_name(PyObject * self,PyObject * args)24102 cert_general_name_type_name(PyObject *self, PyObject *args)
24103 {
24104     unsigned long type;
24105 
24106     TraceMethodEnter(self);
24107 
24108     if (!PyArg_ParseTuple(args, "k:general_name_type_name", &type))
24109         return NULL;
24110 
24111     return general_name_type_to_pystr(type);
24112 }
24113 
24114 PyDoc_STRVAR(cert_general_name_type_from_name_doc,
24115 "general_name_type_from_name(name) -> int\n\
24116 \n\
24117 :Parameters:\n\
24118     name : string\n\
24119         name of CERTGeneralNameType constant\n\
24120 \n\
24121 Given the name of a CERTGeneralNameType constant\n\
24122 return it's integer constant\n\
24123 The string comparison is case insensitive and will match with\n\
24124 or without the cert prefix\n\
24125 ");
24126 static PyObject *
cert_general_name_type_from_name(PyObject * self,PyObject * args)24127 cert_general_name_type_from_name(PyObject *self, PyObject *args)
24128 {
24129     PyObject *py_name;
24130     PyObject *py_lower_name;
24131     PyObject *py_value;
24132 
24133     TraceMethodEnter(self);
24134 
24135     if (!PyArg_ParseTuple(args, "S:general_name_type_from_name", &py_name))
24136         return NULL;
24137 
24138     if ((py_lower_name = PyUnicode_Lower(py_name)) == NULL) {
24139         return NULL;
24140     }
24141 
24142     if ((py_value = PyDict_GetItem(general_name_name_to_value, py_lower_name)) == NULL) {
24143         PyObject *py_name_utf8 = PyBaseString_UTF8(py_name, "GeneralName type name");
24144 	PyErr_Format(PyExc_KeyError, "GeneralName type name not found: %s", PyBytes_AsString(py_name_utf8));
24145         Py_DECREF(py_lower_name);
24146         Py_XDECREF(py_name_utf8);
24147         return NULL;
24148     }
24149 
24150     Py_DECREF(py_lower_name);
24151     Py_INCREF(py_value);
24152 
24153     return py_value;
24154 }
24155 
24156 PyDoc_STRVAR(cert_cert_usage_flags_doc,
24157 "cert_usage_flags(flags, repr_kind=AsEnumDescription) -> ['flag_name', ...]\n\
24158 \n\
24159 :Parameters:\n\
24160     flags : int\n\
24161         certificateUsage* bit flags\n\
24162     repr_kind : RepresentationKind constant\n\
24163         Specifies what the contents of the returned list will be.\n\
24164         May be one of:\n\
24165 \n\
24166         AsEnum\n\
24167             The enumerated constant as an integer value.\n\
24168         AsEnumName\n\
24169             The name of the enumerated constant as a string.\n\
24170         AsEnumDescription\n\
24171             A friendly human readable description of the enumerated constant as a string.\n\
24172 \n\
24173 Given an integer with certificateUsage*\n\
24174 (e.g. nss.certificateUsageSSLServer) bit flags return a sorted\n\
24175 list of their string names.\n\
24176 ");
24177 
24178 static PyObject *
cert_cert_usage_flags(PyObject * self,PyObject * args,PyObject * kwds)24179 cert_cert_usage_flags(PyObject *self, PyObject *args, PyObject *kwds)
24180 {
24181     static char *kwlist[] = {"flags", "repr_kind", NULL};
24182     int flags = 0;
24183     RepresentationKind repr_kind = AsEnumDescription;
24184 
24185     TraceMethodEnter(self);
24186 
24187     if (!PyArg_ParseTupleAndKeywords(args, kwds, "i|i:cert_usage_flags", kwlist,
24188                                      &flags, &repr_kind))
24189         return NULL;
24190 
24191     return cert_usage_flags(flags, repr_kind);
24192 }
24193 
24194 PyDoc_STRVAR(cert_key_usage_flags_doc,
24195 "key_usage_flags(flags, repr_kind=AsEnumName) -> ['flag_name', ...]\n\
24196 \n\
24197 :Parameters:\n\
24198     flags : int\n\
24199         KU_* bit flags\n\
24200     repr_kind : RepresentationKind constant\n\
24201         Specifies what the contents of the returned list will be.\n\
24202         May be one of:\n\
24203 \n\
24204         AsEnum\n\
24205             The enumerated constant as an integer value.\n\
24206         AsEnumName\n\
24207             The name of the enumerated constant as a string.\n\
24208         AsEnumDescription\n\
24209             A friendly human readable description of the enumerated constant as a string.\n\
24210 \n\
24211 Given an integer with KU_*\n\
24212 (e.g. nss.KU_DIGITAL_SIGNATURE) bit flags return a sorted\n\
24213 list of their string names.\n\
24214 ");
24215 
24216 static PyObject *
cert_key_usage_flags(PyObject * self,PyObject * args,PyObject * kwds)24217 cert_key_usage_flags(PyObject *self, PyObject *args, PyObject *kwds)
24218 {
24219     static char *kwlist[] = {"flags", "repr_kind", NULL};
24220     int flags = 0;
24221     RepresentationKind repr_kind = AsEnumName;
24222 
24223     TraceMethodEnter(self);
24224 
24225     if (!PyArg_ParseTupleAndKeywords(args, kwds, "i|i:key_usage_flags", kwlist,
24226                                      &flags, &repr_kind))
24227         return NULL;
24228 
24229     return key_usage_flags(flags, repr_kind);
24230 }
24231 
24232 PyDoc_STRVAR(cert_cert_type_flags_doc,
24233 "cert_type_flags(flags, repr_kind=AsEnumName) -> ['flag_name', ...]\n\
24234 \n\
24235 :Parameters:\n\
24236     flags : int\n\
24237         KU_* bit flags\n\
24238     repr_kind : RepresentationKind constant\n\
24239         Specifies what the contents of the returned list will be.\n\
24240         May be one of:\n\
24241 \n\
24242         AsEnum\n\
24243             The enumerated constant as an integer value.\n\
24244         AsEnumName\n\
24245             The name of the enumerated constant as a string.\n\
24246         AsEnumDescription\n\
24247             A friendly human readable description of the enumerated constant as a string.\n\
24248 \n\
24249 \n\
24250 Given an integer with NS_CERT_TYPE_*\n\
24251 (e.g. nss.NS_CERT_TYPE_SSL_SERVER) bit flags return a sorted\n\
24252 list of their string names.\n\
24253 ");
24254 
24255 static PyObject *
cert_cert_type_flags(PyObject * self,PyObject * args,PyObject * kwds)24256 cert_cert_type_flags(PyObject *self, PyObject *args, PyObject *kwds)
24257 {
24258     static char *kwlist[] = {"flags", "repr_kind", NULL};
24259     int flags = 0;
24260     RepresentationKind repr_kind = AsEnumName;
24261 
24262     TraceMethodEnter(self);
24263 
24264     if (!PyArg_ParseTupleAndKeywords(args, kwds, "i|i:cert_type_flags", kwlist,
24265                           &flags, &repr_kind))
24266         return NULL;
24267 
24268     return cert_type_flags(flags, repr_kind);
24269 }
24270 
24271 PyDoc_STRVAR(nss_nss_init_flags_doc,
24272 "nss_init_flags(flags, repr_kind=AsEnumName) -> ['flag_name', ...]\n\
24273 \n\
24274 :Parameters:\n\
24275     flags : int\n\
24276         NSS_INIT* bit flags\n\
24277     repr_kind : RepresentationKind constant\n\
24278         Specifies what the contents of the returned list will be.\n\
24279         May be one of:\n\
24280 \n\
24281         AsEnum\n\
24282             The enumerated constant as an integer value.\n\
24283         AsEnumName\n\
24284             The name of the enumerated constant as a string.\n\
24285         AsEnumDescription\n\
24286             A friendly human readable description of the enumerated constant as a string.\n\
24287 \n\
24288 \n\
24289 Given an integer with NSS_INIT*\n\
24290 (e.g. nss.NSS_INIT_READONLY) bit flags return a sorted\n\
24291 list of their string names.\n\
24292 ");
24293 
24294 static PyObject *
nss_nss_init_flags(PyObject * self,PyObject * args,PyObject * kwds)24295 nss_nss_init_flags(PyObject *self, PyObject *args, PyObject *kwds)
24296 {
24297     static char *kwlist[] = {"flags", "repr_kind", NULL};
24298     int flags = 0;
24299     RepresentationKind repr_kind = AsEnumName;
24300 
24301     TraceMethodEnter(self);
24302 
24303     if (!PyArg_ParseTupleAndKeywords(args, kwds, "i:nss_init_flags", kwlist,
24304                           &flags, &repr_kind))
24305         return NULL;
24306 
24307     return nss_init_flags(flags, repr_kind);
24308 }
24309 
24310 PyDoc_STRVAR(pkcs12_enable_cipher_doc,
24311 "pkcs12_enable_cipher(cipher, enabled)\n\
24312 \n\
24313 :Parameters:\n\
24314     cipher : integer\n\
24315         The PKCS12 cipher suite enumeration (e.g. `PKCS12_DES_EDE3_168`, etc.)\n\
24316     enabled : bool or int\n\
24317         True enables, False disables\n\
24318 \n\
24319 The cipher may be one of: \n\
24320     - PKCS12_RC2_CBC_40 \n\
24321     - PKCS12_RC2_CBC_128 \n\
24322     - PKCS12_RC4_40 \n\
24323     - PKCS12_RC4_128 \n\
24324     - PKCS12_DES_56 \n\
24325     - PKCS12_DES_EDE3_168 \n\
24326 ");
24327 
24328 static PyObject *
pkcs12_enable_cipher(PyObject * self,PyObject * args)24329 pkcs12_enable_cipher(PyObject *self, PyObject *args)
24330 {
24331     long cipher;
24332     int enabled;
24333 
24334     TraceMethodEnter(self);
24335 
24336     if (!PyArg_ParseTuple(args, "li:pkcs12_enable_cipher", &cipher, &enabled))
24337         return NULL;
24338 
24339     if (SEC_PKCS12EnableCipher(cipher, enabled ? PR_TRUE : PR_FALSE) != SECSuccess) {
24340         PyObject *py_name = pkcs12_cipher_to_pystr(cipher);
24341         PyObject *py_name_utf8 = PyBaseString_UTF8(py_name, "cipher name");
24342         PyObject *py_err_msg = PyBytes_FromFormat("Failed to %s %s (%lx) pkcs12 cipher",
24343                                                   enabled ? _("enable") : _("disable"),
24344                                                   PyBytes_AS_STRING(py_name_utf8), cipher);
24345         set_nspr_error("%s", PyBytes_AsString(py_err_msg));
24346         Py_DECREF(py_name);
24347         Py_XDECREF(py_name_utf8);
24348         Py_DECREF(py_err_msg);
24349         return NULL;
24350     }
24351 
24352     Py_RETURN_NONE;
24353 }
24354 
24355 PyDoc_STRVAR(pkcs12_enable_all_ciphers_doc,
24356 "pkcs12_enable_all_ciphers()\n\
24357 \n\
24358 Enables all PKCS12 ciphers, which are: \n\
24359     - `PKCS12_RC2_CBC_40` \n\
24360     - `PKCS12_RC2_CBC_128` \n\
24361     - `PKCS12_RC4_40` \n\
24362     - `PKCS12_RC4_128` \n\
24363     - `PKCS12_DES_56` \n\
24364     - `PKCS12_DES_EDE3_168` \n\
24365 ");
24366 
24367 static PyObject *
pkcs12_enable_all_ciphers(PyObject * self,PyObject * args)24368 pkcs12_enable_all_ciphers(PyObject *self, PyObject *args)
24369 {
24370     int i;
24371     long cipher;
24372     long all_ciphers[] = {PKCS12_RC4_40,
24373                           PKCS12_RC4_128,
24374                           PKCS12_RC2_CBC_40,
24375                           PKCS12_RC2_CBC_128,
24376                           PKCS12_DES_56,
24377                           PKCS12_DES_EDE3_168};
24378 
24379     TraceMethodEnter(self);
24380 
24381     for (i = 0; i < sizeof(all_ciphers)/sizeof(all_ciphers[0]); i++) {
24382         cipher = all_ciphers[i];
24383         if (SEC_PKCS12EnableCipher(cipher, PR_TRUE) != SECSuccess) {
24384             PyObject *py_name = pkcs12_cipher_to_pystr(cipher);
24385             PyObject *py_name_utf8 = PyBaseString_UTF8(py_name, "cipher name");
24386             PyObject *py_err_msg = PyBytes_FromFormat("Failed to enable %s (%lx) pkcs12 cipher",
24387                                                       PyBytes_AsString(py_name_utf8), cipher);
24388             set_nspr_error("%s", PyBytes_AsString(py_err_msg));
24389             Py_DECREF(py_name);
24390             Py_XDECREF(py_name_utf8);
24391             Py_DECREF(py_err_msg);
24392             return NULL;
24393         }
24394     }
24395 
24396     Py_RETURN_NONE;
24397 }
24398 
24399 PyDoc_STRVAR(pkcs12_set_preferred_cipher_doc,
24400 "pkcs12_set_preferred_cipher(cipher, enabled)\n\
24401 \n\
24402 :Parameters:\n\
24403     cipher : integer\n\
24404         The PKCS12 cipher suite enumeration (e.g. `PKCS12_DES_EDE3_168`, etc.)\n\
24405     enabled : bool or int\n\
24406         True enables, False disables\n\
24407 \n\
24408 This function enables or disables the preferred flag on a \n\
24409 PKCS cipher. The default preferred cipher is `PKCS12_RC2_CBC_40`.\n\
24410 \n\
24411 The cipher may be one of: \n\
24412     - `PKCS12_RC2_CBC_40` \n\
24413     - `PKCS12_RC2_CBC_128` \n\
24414     - `PKCS12_RC4_40` \n\
24415     - `PKCS12_RC4_128` \n\
24416     - `PKCS12_DES_56` \n\
24417     - `PKCS12_DES_EDE3_168` \n\
24418 ");
24419 
24420 static PyObject *
pkcs12_set_preferred_cipher(PyObject * self,PyObject * args)24421 pkcs12_set_preferred_cipher(PyObject *self, PyObject *args)
24422 {
24423     long cipher;
24424     int enabled;
24425 
24426     TraceMethodEnter(self);
24427 
24428     if (!PyArg_ParseTuple(args, "li:pkcs12_set_preferred_cipher", &cipher, &enabled))
24429         return NULL;
24430 
24431     if (SEC_PKCS12SetPreferredCipher(cipher, enabled ? PR_TRUE : PR_FALSE) != SECSuccess) {
24432         return set_nspr_error(NULL);
24433     }
24434 
24435     Py_RETURN_NONE;
24436 }
24437 
24438 static void
pkcs12_export_feed(void * arg,const char * buf,unsigned long len)24439 pkcs12_export_feed(void *arg, const char *buf, unsigned long len)
24440 {
24441     PyObject **py_encoded_buf = arg;
24442     PyObject *py_new_string = NULL;
24443 
24444     if (*py_encoded_buf == NULL) {
24445 	return;
24446     }
24447 
24448     if ((py_new_string = PyBytes_FromStringAndSize(buf, len)) == NULL) {
24449         Py_CLEAR(*py_encoded_buf);
24450         return;
24451     }
24452 
24453     PyBytes_ConcatAndDel(py_encoded_buf, py_new_string);
24454 }
24455 
24456 PyDoc_STRVAR(pkcs12_export_doc,
24457 "pkcs12_export(nickname, pkcs12_password, key_cipher=SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC, cert_cipher=SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC, pin_args=None) \n\
24458 \n\
24459 :Parameters:\n\
24460     nickname : string\n\
24461         Certificate nickname to search for.\n\
24462     pkcs12_password : string\n\
24463         The password used to protect the pkcs12_file.\n\
24464     key_cipher : int\n\
24465         A SEC OID TAG enumerated constant selecting the\n\
24466         encryption for the private key (see below).\n\
24467         Also see `nss.pkcs12_map_cipher()` for an alternative\n\
24468         method to select the encryption cipher.\n\
24469     cert_cipher : int\n\
24470         A SEC OID TAG enumerated constant selecting the\n\
24471         encryption for the certificates (see below).\n\
24472         Also see `nss.pkcs12_map_cipher()` for an alternative\n\
24473         method to select the encryption cipher.\n\
24474     pin_args : tuple\n\
24475         Extra parameters which will\n\
24476         be passed to the password callback function.\n\
24477 \n\
24478 pkcs12_export() is used to export a certificate and private key pair\n\
24479 from the NSS database in a protected manner. It produces the binary\n\
24480 content of what is typically called a .p12 file (e.g. PKCS12). This\n\
24481 function does not write the file, if you want to write a .p12 file\n\
24482 you must write it's output to a file, for example:\n\
24483 \n\
24484 ::\n\
24485 \n\
24486     pkcs12_data = nss.pkcs12_export(nickname, pkcs12_file_password)\n\
24487     f = open(p12_file_path, 'w')\n\
24488     f.write(pkcs12_data)\n\
24489     f.close()\n\
24490 \n\
24491 Password Based Encryption\n\
24492 -------------------------\n\
24493 \n\
24494 PKCS #12 provides for not only the protection of the private keys but\n\
24495 also the certificate and meta-data associated with the keys. Password\n\
24496 based encryption is used to protect private keys (i.e. key_cipher) on\n\
24497 export to a PKCS #12 file and also the entire package when allowed\n\
24498 (i.e. cert_cipher). If no algorithm is specified it defaults to using\n\
24499 'PKCS #12 V2 PBE With SHA-1 And 3KEY Triple DES-CBC' for private key\n\
24500 encryption. For historical export control reasons 'PKCS #12 V2 PBE\n\
24501 With SHA-1 And 40 Bit RC2 CBC' is the default for the overall package\n\
24502 encryption when not in FIPS mode and no package encryption when in\n\
24503 FIPS mode. The private key is always protected with strong encryption\n\
24504 by default.\n\
24505 \n\
24506 A list of ciphers follows, the term is the SEC OID TAG followd by a\n\
24507 friendly description.\n\
24508 \n\
24509 * symmetric CBC ciphers for PKCS #5 V2:\n\
24510     SEC_OID_DES_CBC\n\
24511         DES-CBC.\n\
24512     SEC_OID_RC2_CBC\n\
24513         RC2-CBC.\n\
24514     SEC_OID_RC5_CBC_PAD\n\
24515         RC5-CBCPad.\n\
24516     SEC_OID_DES_EDE3_CBC\n\
24517         DES-EDE3-CBC.\n\
24518     SEC_OID_AES_128_CBC\n\
24519         AES-128-CBC.\n\
24520     SEC_OID_AES_192_CBC\n\
24521         AES-192-CBC.\n\
24522     SEC_OID_AES_256_CBC\n\
24523         AES-256-CBC.\n\
24524     SEC_OID_CAMELLIA_128_CBC\n\
24525         CAMELLIA-128-CBC.\n\
24526     SEC_OID_CAMELLIA_192_CBC\n\
24527         CAMELLIA-192-CBC.\n\
24528     SEC_OID_CAMELLIA_256_CBC\n\
24529         CAMELLIA-256-CBC.\n\
24530 \n\
24531 * PKCS #12 PBE Ciphers:\n\
24532     SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4\n\
24533         PKCS #12 PBE With SHA-1 and 128 Bit RC4.\n\
24534     SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4\n\
24535         PKCS #12 PBE With SHA-1 and 40 Bit RC4.\n\
24536     SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC\n\
24537         PKCS #12 PBE With SHA-1 and Triple DES-CBC.\n\
24538     SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC\n\
24539         PKCS #12 PBE With SHA-1 and 128 Bit RC2 CBC.\n\
24540     SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC\n\
24541         PKCS #12 PBE With SHA-1 and 40 Bit RC2 CBC.\n\
24542     SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4\n\
24543         PKCS #12 V2 PBE With SHA-1 And 128 Bit RC4.\n\
24544     SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4\n\
24545         PKCS #12 V2 PBE With SHA-1 And 40 Bit RC4.\n\
24546     SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC\n\
24547         PKCS #12 V2 PBE With SHA-1 And 3KEY Triple DES-CBC.\n\
24548     SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC\n\
24549         PKCS #12 V2 PBE With SHA-1 And 2KEY Triple DES-CBC.\n\
24550     SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC\n\
24551         PKCS #12 V2 PBE With SHA-1 And 128 Bit RC2 CBC.\n\
24552     SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC\n\
24553         PKCS #12 V2 PBE With SHA-1 And 40 Bit RC2 CBC.\n\
24554 \n\
24555 * PKCS #5 PBE Ciphers:\n\
24556     SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC\n\
24557         PKCS #5 Password Based Encryption with MD2 and DES-CBC.\n\
24558     SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC\n\
24559         PKCS #5 Password Based Encryption with MD5 and DES-CBC.\n\
24560     SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC\n\
24561         PKCS #5 Password Based Encryption with SHA-1 and DES-CBC.\n\
24562 \n\
24563 ");
24564 
24565 static PyObject *
pkcs12_export(PyObject * self,PyObject * args,PyObject * kwds)24566 pkcs12_export(PyObject *self, PyObject *args, PyObject *kwds)
24567 {
24568     static char *kwlist[] = {"nickname", "pkcs12_password", "key_cipher",
24569                              "cert_cipher", "pin_args", NULL};
24570     char *utf8_nickname = NULL;
24571     char *utf8_pkcs12_password = NULL;
24572     Py_ssize_t utf8_pkcs12_password_len = 0;
24573     unsigned int key_cipher = SEC_OID_UNKNOWN;
24574     unsigned int cert_cipher = SEC_OID_UNKNOWN;
24575     PyObject *pin_args = Py_None;
24576     PyObject *py_encoded_buf = NULL;
24577 
24578     SEC_PKCS12ExportContext *export_ctx = NULL;
24579     SEC_PKCS12SafeInfo *key_safe = NULL, *cert_safe = NULL;
24580     SECItem utf8_pkcs12_password_item = {siUTF8String, NULL, 0};
24581     CERTCertList* cert_list = NULL;
24582     CERTCertListNode* node = NULL;
24583     PK11SlotInfo* slot = NULL;
24584 
24585     TraceMethodEnter(self);
24586 
24587     /*
24588      * NSS WART
24589      * Despite the name UCS2_ASCIIConversion it's really UCS2 <-> arbitrary_encoding.
24590      */
24591     PORT_SetUCS2_ASCIIConversionFunction(secport_ucs2_to_utf8);
24592 
24593     key_cipher = SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC;
24594     cert_cipher = PK11_IsFIPS() ? SEC_OID_UNKNOWN : SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC;
24595 
24596     if (!PyArg_ParseTupleAndKeywords(args, kwds, "eses#|IIO&:pkcs12_export", kwlist,
24597                                      "utf-8", &utf8_nickname,
24598                                      "utf-8", &utf8_pkcs12_password, &utf8_pkcs12_password_len,
24599                                      &key_cipher, &cert_cipher,
24600                                      TupleOrNoneConvert, &pin_args))
24601         return NULL;
24602 
24603     utf8_pkcs12_password_item.len = utf8_pkcs12_password_len;
24604     utf8_pkcs12_password_item.data = (unsigned char *)utf8_pkcs12_password;
24605     if (PyNone_Check(pin_args)) {
24606         pin_args = NULL;
24607     }
24608 
24609     Py_BEGIN_ALLOW_THREADS
24610     if ((cert_list = PK11_FindCertsFromNickname(utf8_nickname, pin_args)) == NULL) {
24611 	Py_BLOCK_THREADS
24612         PyErr_Format(PyExc_ValueError, "failed to find certs for nickname = \"%s\"", utf8_nickname);
24613         goto exit;
24614     }
24615     Py_END_ALLOW_THREADS
24616 
24617     /* User certs are those with private keys, retain only those */
24618     if (CERT_FilterCertListForUserCerts(cert_list) != SECSuccess ||
24619         CERT_LIST_EMPTY(cert_list)) {
24620         PyErr_Format(PyExc_ValueError, "no certs with keys for nickname = \"%s\"", utf8_nickname);
24621         goto exit;
24622     }
24623 
24624     if (cert_list) {
24625         CERTCertificate* cert = NULL;
24626         node = CERT_LIST_HEAD(cert_list);
24627         if (node) {
24628             cert = node->cert;
24629         }
24630         if (cert) {
24631             /* Use the slot from the first matching certificate to
24632              * create the context. This is for keygen */
24633             slot = cert->slot;
24634         }
24635     }
24636 
24637     if (!slot) {
24638         PyErr_SetString(PyExc_ValueError, "cert does not have a slot");
24639         goto exit;
24640     }
24641 
24642     if ((export_ctx = SEC_PKCS12CreateExportContext(NULL, NULL, slot, pin_args)) == NULL) {
24643         set_nspr_error("export context creation failed");
24644         goto exit;
24645     }
24646 
24647     if (SEC_PKCS12AddPasswordIntegrity(export_ctx, &utf8_pkcs12_password_item, SEC_OID_SHA1) != SECSuccess) {
24648         set_nspr_error("PKCS12 add password integrity failed");
24649         goto exit;
24650     }
24651 
24652     for (node = CERT_LIST_HEAD(cert_list); !CERT_LIST_END(node,cert_list); node = CERT_LIST_NEXT(node)) {
24653         CERTCertificate* cert = node->cert;
24654         if (!cert->slot) {
24655             PyErr_SetString(PyExc_ValueError, "cert does not have a slot");
24656             goto exit;
24657         }
24658 
24659         key_safe = SEC_PKCS12CreateUnencryptedSafe(export_ctx);
24660         if (cert_cipher == SEC_OID_UNKNOWN) {
24661             cert_safe = key_safe;
24662         } else {
24663             cert_safe = SEC_PKCS12CreatePasswordPrivSafe(export_ctx, &utf8_pkcs12_password_item, cert_cipher);
24664         }
24665 
24666         if (!cert_safe || !key_safe) {
24667             PyErr_SetString(PyExc_ValueError, "key or cert safe creation failed");
24668             goto exit;
24669         }
24670 
24671         if (SEC_PKCS12AddCertAndKey(export_ctx, cert_safe, NULL, cert,
24672                                     CERT_GetDefaultCertDB(), key_safe, NULL,
24673                                     PR_TRUE, &utf8_pkcs12_password_item, key_cipher) != SECSuccess) {
24674             set_nspr_error("add cert and key failed");
24675             goto exit;
24676         }
24677     }
24678 
24679     if ((py_encoded_buf = PyBytes_FromStringAndSize(NULL, 0)) == NULL) {
24680         goto exit;
24681     }
24682 
24683     if (SEC_PKCS12Encode(export_ctx, pkcs12_export_feed, &py_encoded_buf) != SECSuccess) {
24684         set_nspr_error("PKCS12 encode failed");
24685         Py_CLEAR(py_encoded_buf);
24686         goto exit;
24687     }
24688 
24689  exit:
24690     if (utf8_nickname) {
24691         PyMem_Free(utf8_nickname);
24692     }
24693     if (utf8_pkcs12_password) {
24694         PyMem_Free(utf8_pkcs12_password);
24695     }
24696     if (cert_list) {
24697         CERT_DestroyCertList(cert_list);
24698     }
24699     if (export_ctx) {
24700         SEC_PKCS12DestroyExportContext(export_ctx);
24701     }
24702 
24703     return py_encoded_buf;
24704 }
24705 
24706 PyDoc_STRVAR(nss_fingerprint_format_lines_doc,
24707 "fingerprint_format_lines(data, level=0) -> \n\
24708 \n\
24709 :Parameters:\n\
24710     data : SecItem or str or any buffer compatible object\n\
24711         Data to initialize the certificate request from, must be in DER format\n\
24712     level : integer\n\
24713         Initial indentation level, all subsequent indents are relative\n\
24714         to this starting level.\n\
24715 \n\
24716 Generates digests of data (i.e. fingerprint) and formats\n\
24717 it into line tuples for text output.\n\
24718 ");
24719 
24720 static PyObject *
nss_fingerprint_format_lines(PyObject * self,PyObject * args,PyObject * kwds)24721 nss_fingerprint_format_lines(PyObject *self, PyObject *args, PyObject *kwds)
24722 {
24723     static char *kwlist[] = {"data", "level", NULL};
24724     int level = 0;
24725     SECItem_param *data_param = NULL;
24726     PyObject *result = NULL;
24727 
24728     TraceMethodEnter(self);
24729 
24730     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&|i:fingerprint_format_lines", kwlist,
24731                                      SECItemConvert, &data_param, &level))
24732         return NULL;
24733 
24734     result = fingerprint_format_lines(&data_param->item, level);
24735     SECItem_param_release(data_param);
24736     return result;
24737 }
24738 
24739 PyDoc_STRVAR(cert_get_use_pkix_for_validation_doc,
24740 "get_use_pkix_for_validation() -> flag\n\
24741 \n\
24742 Returns the current value of the flag used to enable or disable the\n\
24743 use of PKIX for certificate validation. See also:\n\
24744 `set_use_pkix_for_validation`.\n\
24745 ");
24746 
24747 static PyObject *
cert_get_use_pkix_for_validation(PyObject * self,PyObject * args)24748 cert_get_use_pkix_for_validation(PyObject *self, PyObject *args)
24749 {
24750     PRBool flag;
24751 
24752     TraceMethodEnter(self);
24753 
24754     flag = CERT_GetUsePKIXForValidation();
24755 
24756     if (flag) {
24757         Py_RETURN_TRUE;
24758     } else {
24759         Py_RETURN_FALSE;
24760     }
24761 }
24762 
24763 PyDoc_STRVAR(cert_set_use_pkix_for_validation_doc,
24764 "set_use_pkix_for_validation(flag) -> prev_flag\n\
24765 \n\
24766 :Parameters:\n\
24767     flag : bool\n\
24768         Boolean flag, True to enable PKIX validation,\n\
24769         False to disable PKIX validation.\n\
24770 \n\
24771 Sets the flag to enable or disable the use of PKIX for certificate\n\
24772 validation. Returns the previous value of the flag.\n\
24773 See also: `get_use_pkix_for_validation`.\n\
24774 ");
24775 
24776 static PyObject *
cert_set_use_pkix_for_validation(PyObject * self,PyObject * args)24777 cert_set_use_pkix_for_validation(PyObject *self, PyObject *args)
24778 {
24779     int flag;
24780     PRBool prev_flag;
24781 
24782     TraceMethodEnter(self);
24783 
24784     if (!PyArg_ParseTuple(args, "i:set_use_pkix_for_validation",
24785                           &flag))
24786         return NULL;
24787 
24788     prev_flag = CERT_GetUsePKIXForValidation();
24789 
24790     if (CERT_SetUsePKIXForValidation(flag ? PR_TRUE : PR_FALSE) != SECSuccess) {
24791         return set_nspr_error(NULL);
24792     }
24793 
24794     if (prev_flag) {
24795         Py_RETURN_TRUE;
24796     } else {
24797         Py_RETURN_FALSE;
24798     }
24799 }
24800 
24801 PyDoc_STRVAR(cert_enable_ocsp_checking_doc,
24802 "enable_ocsp_checking(certdb=get_default_certdb())\n\
24803 \n\
24804 :Parameters:\n\
24805     certdb : CertDB object or None\n\
24806         CertDB certificate database object, if None then the default\n\
24807         certdb will be supplied by calling `nss.get_default_certdb()`.\n\
24808 \n\
24809 Turns on OCSP checking for the given certificate database.\n\
24810 ");
24811 
24812 static PyObject *
cert_enable_ocsp_checking(PyObject * self,PyObject * args,PyObject * kwds)24813 cert_enable_ocsp_checking(PyObject *self, PyObject *args, PyObject *kwds)
24814 {
24815     static char *kwlist[] = {"certdb", NULL};
24816     CertDB *py_certdb = NULL;
24817     CERTCertDBHandle *certdb_handle = NULL;
24818 
24819     TraceMethodEnter(self);
24820 
24821     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O!:enable_ocsp_checking", kwlist,
24822                                      &CertDBType, &py_certdb))
24823         return NULL;
24824 
24825     if (py_certdb) {
24826         certdb_handle = py_certdb->handle;
24827     } else {
24828         certdb_handle = CERT_GetDefaultCertDB();
24829     }
24830 
24831     if (CERT_EnableOCSPChecking(certdb_handle) != SECSuccess) {
24832         return set_nspr_error(NULL);
24833     }
24834 
24835     Py_RETURN_NONE;
24836 }
24837 
24838 PyDoc_STRVAR(cert_disable_ocsp_checking_doc,
24839 "disable_ocsp_checking(certdb=get_default_certdb())\n\
24840 \n\
24841 :Parameters:\n\
24842     certdb : CertDB object or None\n\
24843         CertDB certificate database object, if None then the default\n\
24844         certdb will be supplied by calling `nss.get_default_certdb()`.\n\
24845 \n\
24846 Turns off OCSP checking for the given certificate database. It will\n\
24847 raise an exception with SEC_ERROR_OCSP_NOT_ENABLED as the error code\n\
24848 if OCSP checking is not enabled. It is safe to call it when OCSP\n\
24849 checking is disabled, you can just ignore the exception if it is\n\
24850 easier to just call it than to remember if it was enabled.\n\
24851 ");
24852 
24853 static PyObject *
cert_disable_ocsp_checking(PyObject * self,PyObject * args,PyObject * kwds)24854 cert_disable_ocsp_checking(PyObject *self, PyObject *args, PyObject *kwds)
24855 {
24856     static char *kwlist[] = {"certdb", NULL};
24857     CertDB *py_certdb = NULL;
24858     CERTCertDBHandle *certdb_handle = NULL;
24859 
24860     TraceMethodEnter(self);
24861 
24862     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O!:disable_ocsp_checking", kwlist,
24863                                      &CertDBType, &py_certdb))
24864         return NULL;
24865 
24866     if (py_certdb) {
24867         certdb_handle = py_certdb->handle;
24868     } else {
24869         certdb_handle = CERT_GetDefaultCertDB();
24870     }
24871 
24872     if (CERT_DisableOCSPChecking(certdb_handle) != SECSuccess) {
24873         return set_nspr_error(NULL);
24874     }
24875 
24876     Py_RETURN_NONE;
24877 }
24878 
24879 PyDoc_STRVAR(cert_set_ocsp_cache_settings_doc,
24880 "set_ocsp_cache_settings(max_cache_entries, min_secs_till_next_fetch, max_secs_till_next_fetch)\n\
24881 \n\
24882 :Parameters:\n\
24883     max_cache_entries : int\n\
24884         Maximum number of cache entries.\n\
24885         Special values, -1 disables the cache, 0 indicates unlimited cache entries.\n\
24886     min_secs_till_next_fetch : int\n\
24887         Whenever an OCSP request was attempted or completed over the network,\n\
24888         wait at least this number of seconds before trying to fetch again.\n\
24889     max_secs_till_next_fetch : int\n\
24890         The maximum age of a cached response we allow, until we try\n\
24891         to fetch an updated response, even if the OCSP responder expects\n\
24892         that a newer information update will not be available yet.\n\
24893 \n\
24894 Sets parameters that control NSS' internal OCSP cache.\n\
24895 ");
24896 static PyObject *
cert_set_ocsp_cache_settings(PyObject * self,PyObject * args)24897 cert_set_ocsp_cache_settings(PyObject *self, PyObject *args)
24898 {
24899     int max_cache_entries;
24900     unsigned int min_secs_till_next_fetch;
24901     unsigned int max_secs_till_next_fetch;
24902 
24903     TraceMethodEnter(self);
24904 
24905     if (!PyArg_ParseTuple(args, "iII:set_ocsp_cache_settings",
24906                           &max_cache_entries,
24907                           &min_secs_till_next_fetch, &max_secs_till_next_fetch))
24908         return NULL;
24909 
24910     if (CERT_OCSPCacheSettings(max_cache_entries,
24911                                min_secs_till_next_fetch,
24912                                max_secs_till_next_fetch) != SECSuccess) {
24913         return set_nspr_error(NULL);
24914     }
24915 
24916     Py_RETURN_NONE;
24917 }
24918 
24919 PyDoc_STRVAR(cert_set_ocsp_failure_mode_doc,
24920 "set_ocsp_failure_mode(failure_mode)\n\
24921 \n\
24922 :Parameters:\n\
24923     failure_mode : int\n\
24924         A ocspMode_Failure* constant\n\
24925 \n\
24926 Set the desired behaviour on OCSP failures.\n\
24927 failure_mode may be one of:\n\
24928 \n\
24929     - ocspMode_FailureIsVerificationFailure\n\
24930     - ocspMode_FailureIsNotAVerificationFailure\n\
24931 \n\
24932 ");
24933 static PyObject *
cert_set_ocsp_failure_mode(PyObject * self,PyObject * args)24934 cert_set_ocsp_failure_mode(PyObject *self, PyObject *args)
24935 {
24936     int failure_mode;
24937 
24938     TraceMethodEnter(self);
24939 
24940     if (!PyArg_ParseTuple(args, "i:set_ocsp_failure_mode",
24941                           &failure_mode))
24942         return NULL;
24943 
24944     if (CERT_SetOCSPFailureMode(failure_mode) != SECSuccess) {
24945         return set_nspr_error(NULL);
24946     }
24947 
24948     Py_RETURN_NONE;
24949 }
24950 
24951 PyDoc_STRVAR(cert_set_ocsp_timeout_doc,
24952 "set_ocsp_timeout(seconds)\n\
24953 \n\
24954 :Parameters:\n\
24955     seconds : int\n\
24956         Maximum number of seconds NSS will wait for an OCSP response.\n\
24957 \n\
24958 Configure the maximum time NSS will wait for an OCSP response.\n\
24959 \n\
24960 ");
24961 static PyObject *
cert_set_ocsp_timeout(PyObject * self,PyObject * args)24962 cert_set_ocsp_timeout(PyObject *self, PyObject *args)
24963 {
24964     unsigned int seconds;
24965 
24966     TraceMethodEnter(self);
24967 
24968     if (!PyArg_ParseTuple(args, "I:set_ocsp_timeout",
24969                           &seconds))
24970         return NULL;
24971 
24972     if (CERT_SetOCSPTimeout(seconds) != SECSuccess) {
24973         return set_nspr_error(NULL);
24974     }
24975 
24976     Py_RETURN_NONE;
24977 }
24978 
24979 PyDoc_STRVAR(cert_clear_ocsp_cache_doc,
24980 "clear_ocsp_cache()\n\
24981 \n\
24982 Removes all items currently stored in the OCSP cache.\n\
24983 \n\
24984 ");
24985 static PyObject *
cert_clear_ocsp_cache(PyObject * self,PyObject * args)24986 cert_clear_ocsp_cache(PyObject *self, PyObject *args)
24987 {
24988     TraceMethodEnter(self);
24989 
24990     if (CERT_ClearOCSPCache() != SECSuccess) {
24991         return set_nspr_error(NULL);
24992     }
24993 
24994     Py_RETURN_NONE;
24995 }
24996 
24997 PyDoc_STRVAR(cert_set_ocsp_default_responder_doc,
24998 "set_ocsp_default_responder(certdb, url, nickname)\n\
24999 \n\
25000 :Parameters:\n\
25001     certdb : CertDB object\n\
25002         CertDB certificate database object.\n\
25003     url : string\n\
25004         The location of the default responder (e.g. \"http://foo.com:80/ocsp\")\n\
25005         Note that the location will not be tested until the first attempt\n\
25006         to send a request there.\n\
25007     nickname : string\n\
25008         The nickname of the cert to trust (expected) to sign the OCSP responses.\n\
25009         If the corresponding cert cannot be found, SECFailure is returned.\n\
25010 \n\
25011 Specify the location and cert of the default responder.  If OCSP\n\
25012 checking is already enabled and use of a default responder is also\n\
25013 already enabled, all OCSP checking from now on will go directly to the\n\
25014 specified responder. If OCSP checking is not enabled, or if it is\n\
25015 enabled but use of a default responder is not enabled, the information\n\
25016 will be recorded and take effect whenever both are enabled.\n\
25017 ");
25018 
25019 static PyObject *
cert_set_ocsp_default_responder(PyObject * self,PyObject * args)25020 cert_set_ocsp_default_responder(PyObject *self, PyObject *args)
25021 {
25022     CertDB *py_certdb = NULL;
25023     PyObject *py_url_utf8 = NULL;
25024     PyObject *py_nickname_utf8 = NULL;
25025 
25026     TraceMethodEnter(self);
25027 
25028     if (!PyArg_ParseTuple(args, "O!O&O&:set_ocsp_default_responder",
25029                           &CertDBType, &py_certdb,
25030                           UTF8Convert, &py_url_utf8,
25031                           UTF8Convert, &py_nickname_utf8))
25032         return NULL;
25033 
25034     if (CERT_SetOCSPDefaultResponder(py_certdb->handle,
25035                                      PyBytes_AS_STRING(py_url_utf8),
25036                                      PyBytes_AS_STRING(py_nickname_utf8)) != SECSuccess) {
25037         return set_nspr_error(NULL);
25038     }
25039 
25040     Py_XDECREF(py_url_utf8);
25041     Py_XDECREF(py_nickname_utf8);
25042 
25043     Py_RETURN_NONE;
25044 }
25045 
25046 PyDoc_STRVAR(cert_enable_ocsp_default_responder_doc,
25047 "enable_ocsp_default_responder(certdb=get_default_certdb())\n\
25048 \n\
25049 :Parameters:\n\
25050     certdb : CertDB object or None\n\
25051         CertDB certificate database object, if None then the default\n\
25052         certdb will be supplied by calling `nss.get_default_certdb()`.\n\
25053 \n\
25054 Turns on use of a default responder when OCSP checking.  If OCSP\n\
25055 checking is already enabled, this will make subsequent checks go\n\
25056 directly to the default responder.  (The location of the responder and\n\
25057 the nickname of the responder cert must already be specified.)  If\n\
25058 OCSP checking is not enabled, this will be recorded and take effect\n\
25059 whenever it is enabled.\n\
25060 ");
25061 static PyObject *
cert_enable_ocsp_default_responder(PyObject * self,PyObject * args,PyObject * kwds)25062 cert_enable_ocsp_default_responder(PyObject *self, PyObject *args, PyObject *kwds)
25063 {
25064     static char *kwlist[] = {"certdb", NULL};
25065     CertDB *py_certdb = NULL;
25066     CERTCertDBHandle *certdb_handle = NULL;
25067 
25068     TraceMethodEnter(self);
25069 
25070     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O!:enable_ocsp_default_responder", kwlist,
25071                                      &CertDBType, &py_certdb))
25072         return NULL;
25073 
25074     if (py_certdb) {
25075         certdb_handle = py_certdb->handle;
25076     } else {
25077         certdb_handle = CERT_GetDefaultCertDB();
25078     }
25079 
25080     if (CERT_EnableOCSPDefaultResponder(certdb_handle) != SECSuccess) {
25081         return set_nspr_error(NULL);
25082     }
25083 
25084     Py_RETURN_NONE;
25085 }
25086 
25087 PyDoc_STRVAR(cert_disable_ocsp_default_responder_doc,
25088 "disable_ocsp_default_responder(certdb=get_default_certdb())\n\
25089 \n\
25090 :Parameters:\n\
25091     certdb : CertDB object or None\n\
25092         CertDB certificate database object, if None then the default\n\
25093         certdb will be supplied by calling `nss.get_default_certdb()`.\n\
25094 \n\
25095 Turns off use of a default responder when OCSP checking.\n\
25096 (Does nothing if use of a default responder is not enabled.)\n\
25097 ");
25098 static PyObject *
cert_disable_ocsp_default_responder(PyObject * self,PyObject * args,PyObject * kwds)25099 cert_disable_ocsp_default_responder(PyObject *self, PyObject *args, PyObject *kwds)
25100 {
25101     static char *kwlist[] = {"certdb", NULL};
25102     CertDB *py_certdb = NULL;
25103     CERTCertDBHandle *certdb_handle = NULL;
25104 
25105     TraceMethodEnter(self);
25106 
25107     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O!:disable_ocsp_default_responder", kwlist,
25108                                      &CertDBType, &py_certdb))
25109         return NULL;
25110 
25111     if (py_certdb) {
25112         certdb_handle = py_certdb->handle;
25113     } else {
25114         certdb_handle = CERT_GetDefaultCertDB();
25115     }
25116 
25117     if (CERT_DisableOCSPDefaultResponder(certdb_handle) != SECSuccess) {
25118         return set_nspr_error(NULL);
25119     }
25120 
25121     Py_RETURN_NONE;
25122 }
25123 
25124 /* List of functions exported by this module. */
25125 static PyMethodDef
25126 module_methods[] = {
25127     {"nss_get_version",                  (PyCFunction)nss_nss_get_version,                 METH_NOARGS,                nss_nss_get_version_doc},
25128     {"nss_version_check",                (PyCFunction)nss_nss_version_check,               METH_VARARGS,               nss_nss_version_check_doc},
25129     {"set_shutdown_callback",            (PyCFunction)nss_set_shutdown_callback,           METH_VARARGS,               nss_set_shutdown_callback_doc},
25130     {"nss_is_initialized",               (PyCFunction)nss_nss_is_initialized,              METH_NOARGS,                nss_nss_is_initialized_doc},
25131     {"nss_init",                         (PyCFunction)nss_nss_init,                        METH_VARARGS,               nss_nss_init_doc},
25132     {"nss_init_read_write",              (PyCFunction)nss_nss_init_read_write,             METH_VARARGS,               nss_nss_init_read_write_doc},
25133     {"nss_init_nodb",                    (PyCFunction)nss_init_nodb,                       METH_NOARGS,                nss_init_nodb_doc},
25134     {"nss_initialize",                   (PyCFunction)nss_nss_initialize,                  METH_VARARGS|METH_KEYWORDS, nss_nss_initialize_doc},
25135     {"nss_init_context",                 (PyCFunction)nss_nss_init_context,                METH_VARARGS|METH_KEYWORDS, nss_nss_init_context_doc},
25136     {"nss_shutdown",                     (PyCFunction)nss_nss_shutdown,                    METH_NOARGS,                nss_nss_shutdown_doc},
25137     {"nss_shutdown_context",             (PyCFunction)nss_nss_shutdown_context,            METH_VARARGS,               nss_nss_shutdown_context_doc},
25138     {"dump_certificate_cache_info",      (PyCFunction)nss_dump_certificate_cache_info,     METH_NOARGS,                nss_dump_certificate_cache_info_doc},
25139     {"set_password_callback",            (PyCFunction)pk11_set_password_callback,          METH_VARARGS,               pk11_set_password_callback_doc},
25140     {"list_certs",                       (PyCFunction)pk11_list_certs,                     METH_VARARGS,               pk11_list_certs_doc},
25141     {"find_certs_from_email_addr",       (PyCFunction)pk11_find_certs_from_email_addr,     METH_VARARGS,               pk11_find_certs_from_email_addr_doc},
25142     {"find_certs_from_nickname",         (PyCFunction)pk11_find_certs_from_nickname,       METH_VARARGS,               pk11_find_certs_from_nickname_doc},
25143     {"find_cert_from_nickname",          (PyCFunction)pk11_find_cert_from_nickname,        METH_VARARGS,               pk11_find_cert_from_nickname_doc},
25144     {"find_key_by_any_cert",             (PyCFunction)pk11_find_key_by_any_cert,           METH_VARARGS,               pk11_find_key_by_any_cert_doc},
25145     {"generate_random",                  (PyCFunction)pk11_generate_random,                METH_VARARGS,               pk11_generate_random_doc},
25146     {"get_default_certdb",               (PyCFunction)cert_get_default_certdb,             METH_NOARGS,                cert_get_default_certdb_doc},
25147     {"get_cert_nicknames",               (PyCFunction)cert_get_cert_nicknames,             METH_VARARGS,               cert_get_cert_nicknames_doc},
25148     {"data_to_hex",                      (PyCFunction)cert_data_to_hex,                    METH_VARARGS|METH_KEYWORDS, cert_data_to_hex_doc},
25149     {"read_hex",                         (PyCFunction)read_hex,                            METH_VARARGS|METH_KEYWORDS, read_hex_doc},
25150     {"hash_buf",                         (PyCFunction)pk11_hash_buf,                       METH_VARARGS,               pk11_hash_buf_doc},
25151     {"md5_digest",                       (PyCFunction)pk11_md5_digest,                     METH_VARARGS,               pk11_md5_digest_doc},
25152     {"sha1_digest",                      (PyCFunction)pk11_sha1_digest,                    METH_VARARGS,               pk11_sha1_digest_doc},
25153     {"sha256_digest",                    (PyCFunction)pk11_sha256_digest,                  METH_VARARGS,               pk11_sha256_digest_doc},
25154     {"sha512_digest",                    (PyCFunction)pk11_sha512_digest,                  METH_VARARGS,               pk11_sha512_digest_doc},
25155     {"indented_format",                  (PyCFunction)py_indented_format,                  METH_VARARGS|METH_KEYWORDS, py_indented_format_doc},
25156     {"make_line_fmt_tuples",             (PyCFunction)py_make_line_fmt_tuples,             METH_VARARGS|METH_KEYWORDS, py_make_line_fmt_tuples_doc},
25157     {"der_universal_secitem_fmt_lines",  (PyCFunction)cert_der_universal_secitem_fmt_lines, METH_VARARGS|METH_KEYWORDS, cert_der_universal_secitem_fmt_lines_doc},
25158     {"oid_str",                          (PyCFunction)cert_oid_str,                        METH_VARARGS,               cert_oid_str_doc},
25159     {"oid_tag_name",                     (PyCFunction)cert_oid_tag_name,                   METH_VARARGS,               cert_oid_tag_name_doc},
25160     {"oid_tag",                          (PyCFunction)cert_oid_tag,                        METH_VARARGS,               cert_oid_tag_doc},
25161     {"oid_dotted_decimal",               (PyCFunction)cert_oid_dotted_decimal,             METH_VARARGS,               cert_oid_dotted_decimal_doc},
25162     {"key_mechanism_type_name",          (PyCFunction)pk11_key_mechanism_type_name,        METH_VARARGS,               pk11_key_mechanism_type_name_doc},
25163     {"key_mechanism_type_from_name",     (PyCFunction)pk11_key_mechanism_type_from_name,   METH_VARARGS,               pk11_key_mechanism_type_from_name_doc},
25164     {"pk11_attribute_type_name",         (PyCFunction)pk11_pk11_attribute_type_name,       METH_VARARGS,               pk11_attribute_type_name_doc},
25165     {"pk11_attribute_type_from_name",    (PyCFunction)pk11_pk11_attribute_type_from_name,  METH_VARARGS,               pk11_pk11_attribute_type_from_name_doc},
25166     {"cert_crl_reason_name",             (PyCFunction)cert_crl_reason_name,                METH_VARARGS,               cert_crl_reason_name_doc},
25167     {"cert_crl_reason_from_name",        (PyCFunction)cert_crl_reason_from_name,           METH_VARARGS,               cert_crl_reason_from_name_doc},
25168     {"cert_general_name_type_name",      (PyCFunction)cert_general_name_type_name,         METH_VARARGS,               cert_general_name_type_name_doc},
25169     {"cert_general_name_type_from_name", (PyCFunction)cert_general_name_type_from_name,    METH_VARARGS,               cert_general_name_type_from_name_doc},
25170     {"pk11_disabled_reason_str",         (PyCFunction)pk11_pk11_disabled_reason_str,       METH_VARARGS,               pk11_disabled_reason_str_doc},
25171     {"pk11_disabled_reason_name",        (PyCFunction)pk11_pk11_disabled_reason_name,      METH_VARARGS,               pk11_disabled_reason_name_doc},
25172     {"pk11_logout_all",                  (PyCFunction)pk11_pk11_logout_all,                METH_NOARGS,                pk11_pk11_logout_all_doc},
25173     {"get_best_slot",                    (PyCFunction)pk11_get_best_slot,                  METH_VARARGS,               pk11_get_best_slot_doc},
25174     {"get_internal_slot",                (PyCFunction)pk11_get_internal_slot,              METH_NOARGS,                pk11_get_internal_slot_doc},
25175     {"get_internal_key_slot",            (PyCFunction)pk11_get_internal_key_slot,          METH_NOARGS,                pk11_get_internal_key_slot_doc},
25176     {"get_all_tokens",                   (PyCFunction)pk11_get_all_tokens,                 METH_VARARGS|METH_KEYWORDS, pk11_get_all_tokens_doc},
25177     {"find_slot_by_name",                (PyCFunction)pk11_find_slot_by_name,              METH_VARARGS,               pk11_find_slot_by_name_doc},
25178     {"create_context_by_sym_key",        (PyCFunction)pk11_create_context_by_sym_key,      METH_VARARGS|METH_KEYWORDS, pk11_create_context_by_sym_key_doc},
25179     {"import_sym_key",                   (PyCFunction)pk11_import_sym_key,                 METH_VARARGS,               pk11_import_sym_key_doc},
25180     {"pub_wrap_sym_key",                 (PyCFunction)pk11_pub_wrap_sym_key,               METH_VARARGS,               pk11_pub_wrap_sym_key_doc},
25181     {"create_digest_context",            (PyCFunction)pk11_create_digest_context,          METH_VARARGS,               pk11_create_digest_context_doc},
25182     {"param_from_iv",                    (PyCFunction)pk11_param_from_iv,                  METH_VARARGS|METH_KEYWORDS, pk11_param_from_iv_doc},
25183     {"param_from_algid",                 (PyCFunction)pk11_param_from_algid,               METH_VARARGS,               pk11_param_from_algid_doc},
25184     {"generate_new_param",               (PyCFunction)pk11_generate_new_param,             METH_VARARGS|METH_KEYWORDS, pk11_generate_new_param_doc},
25185     {"algtag_to_mechanism",              (PyCFunction)pk11_algtag_to_mechanism,            METH_VARARGS,               pk11_algtag_to_mechanism_doc},
25186     {"mechanism_to_algtag",              (PyCFunction)pk11_mechanism_to_algtag,            METH_VARARGS,               pk11_mechanism_to_algtag_doc},
25187     {"get_iv_length",                    (PyCFunction)pk11_get_iv_length,                  METH_VARARGS,               pk11_get_iv_length_doc},
25188     {"get_block_size",                   (PyCFunction)pk11_get_block_size,                 METH_VARARGS|METH_KEYWORDS, pk11_get_block_size_doc},
25189     {"get_pad_mechanism",                (PyCFunction)pk11_get_pad_mechanism,              METH_VARARGS,               pk11_get_pad_mechanism_doc},
25190     {"import_crl",                       (PyCFunction)pk11_import_crl,                     METH_VARARGS,               pk11_import_crl_doc},
25191     {"create_pbev2_algorithm_id",        (PyCFunction)pk11_create_pbev2_algorithm_id,      METH_VARARGS|METH_KEYWORDS, pk11_create_pbev2_algorithm_id_doc},
25192     {"need_pw_init",                     (PyCFunction)pk11_pk11_need_pw_init,              METH_NOARGS,                pk11_pk11_need_pw_init_doc},
25193     {"token_exists",                     (PyCFunction)pk11_pk11_token_exists,              METH_NOARGS,                pk11_pk11_token_exists_doc},
25194     {"is_fips",                          (PyCFunction)pk11_pk11_is_fips,                   METH_NOARGS,                pk11_pk11_is_fips_doc},
25195     {"decode_der_crl",                   (PyCFunction)cert_decode_der_crl,                 METH_VARARGS|METH_KEYWORDS, cert_decode_der_crl_doc},
25196     {"read_der_from_file",               (PyCFunction)nss_read_der_from_file,              METH_VARARGS|METH_KEYWORDS, nss_read_der_from_file_doc},
25197     {"base64_to_binary",                 (PyCFunction)nss_base64_to_binary,                METH_VARARGS|METH_KEYWORDS, nss_base64_to_binary_doc},
25198     {"x509_key_usage",                   (PyCFunction)cert_x509_key_usage,                 METH_VARARGS|METH_KEYWORDS, cert_x509_key_usage_doc},
25199     {"x509_cert_type",                   (PyCFunction)cert_x509_cert_type,                 METH_VARARGS|METH_KEYWORDS, cert_x509_cert_type_doc},
25200     {"x509_ext_key_usage",               (PyCFunction)cert_x509_ext_key_usage,             METH_VARARGS|METH_KEYWORDS, cert_x509_ext_key_usage_doc},
25201     {"x509_alt_name",                    (PyCFunction)cert_x509_alt_name,                  METH_VARARGS|METH_KEYWORDS, cert_x509_alt_name_doc},
25202     {"cert_usage_flags",                 (PyCFunction)cert_cert_usage_flags,               METH_VARARGS|METH_KEYWORDS, cert_cert_usage_flags_doc},
25203     {"key_usage_flags",                  (PyCFunction)cert_key_usage_flags,                METH_VARARGS|METH_KEYWORDS, cert_key_usage_flags_doc},
25204     {"cert_type_flags",                  (PyCFunction)cert_cert_type_flags,                METH_VARARGS|METH_KEYWORDS, cert_cert_type_flags_doc},
25205     {"nss_init_flags",                   (PyCFunction)nss_nss_init_flags,                  METH_VARARGS|METH_KEYWORDS, nss_nss_init_flags_doc},
25206     {"pkcs12_enable_cipher",             (PyCFunction)pkcs12_enable_cipher,                METH_VARARGS,               pkcs12_enable_cipher_doc},
25207     {"pkcs12_enable_all_ciphers",        (PyCFunction)pkcs12_enable_all_ciphers,           METH_NOARGS,                pkcs12_enable_all_ciphers_doc},
25208     {"pkcs12_set_preferred_cipher",      (PyCFunction)pkcs12_set_preferred_cipher,         METH_VARARGS,               pkcs12_set_preferred_cipher_doc},
25209     {"pkcs12_cipher_name",               (PyCFunction)pkcs12_cipher_name,                  METH_VARARGS,               pkcs12_cipher_name_doc},
25210     {"pkcs12_cipher_from_name",          (PyCFunction)pkcs12_cipher_from_name,             METH_VARARGS,               pkcs12_cipher_from_name_doc},
25211     {"pkcs12_map_cipher",                (PyCFunction)pkcs12_map_cipher,                   METH_VARARGS|METH_KEYWORDS, pkcs12_map_cipher_doc},
25212     {"pkcs12_set_nickname_collision_callback", (PyCFunction)PKCS12_pkcs12_set_nickname_collision_callback, METH_VARARGS,      PKCS12_pkcs12_set_nickname_collision_callback_doc},
25213     {"pkcs12_export",                    (PyCFunction)pkcs12_export,                       METH_VARARGS|METH_KEYWORDS, pkcs12_export_doc},
25214     {"fingerprint_format_lines",         (PyCFunction)nss_fingerprint_format_lines,        METH_VARARGS|METH_KEYWORDS, nss_fingerprint_format_lines_doc},
25215     {"get_use_pkix_for_validation",      (PyCFunction)cert_get_use_pkix_for_validation,    METH_NOARGS,                cert_get_use_pkix_for_validation_doc},
25216     {"set_use_pkix_for_validation",      (PyCFunction)cert_set_use_pkix_for_validation,    METH_VARARGS,               cert_set_use_pkix_for_validation_doc},
25217     {"enable_ocsp_checking",             (PyCFunction)cert_enable_ocsp_checking,           METH_VARARGS|METH_KEYWORDS, cert_enable_ocsp_checking_doc},
25218     {"disable_ocsp_checking",            (PyCFunction)cert_disable_ocsp_checking,          METH_VARARGS|METH_KEYWORDS, cert_disable_ocsp_checking_doc},
25219     {"set_ocsp_cache_settings",          (PyCFunction)cert_set_ocsp_cache_settings,        METH_VARARGS,               cert_set_ocsp_cache_settings_doc},
25220     {"set_ocsp_failure_mode",            (PyCFunction)cert_set_ocsp_failure_mode,          METH_VARARGS,               cert_set_ocsp_failure_mode_doc},
25221     {"set_ocsp_timeout",                 (PyCFunction)cert_set_ocsp_timeout,               METH_VARARGS,               cert_set_ocsp_timeout_doc},
25222     {"clear_ocsp_cache",                 (PyCFunction)cert_clear_ocsp_cache,               METH_NOARGS,                cert_clear_ocsp_cache_doc},
25223     {"set_ocsp_default_responder",       (PyCFunction)cert_set_ocsp_default_responder,     METH_VARARGS,               cert_set_ocsp_default_responder_doc},
25224     {"enable_ocsp_default_responder",    (PyCFunction)cert_enable_ocsp_default_responder,  METH_VARARGS|METH_KEYWORDS, cert_enable_ocsp_default_responder_doc},
25225     {"disable_ocsp_default_responder",   (PyCFunction)cert_disable_ocsp_default_responder, METH_VARARGS|METH_KEYWORDS, cert_disable_ocsp_default_responder_doc},
25226     {NULL, NULL} /* Sentinel */
25227 };
25228 
25229 /* ============================== Module Exports ============================= */
25230 
25231 static PyNSPR_NSS_C_API_Type nspr_nss_c_api =
25232 {
25233     &PK11SlotType,
25234     &CertDBType,
25235     &CertificateType,
25236     &PrivateKeyType,
25237     &SecItemType,
25238     Certificate_new_from_CERTCertificate,
25239     PrivateKey_new_from_SECKEYPrivateKey,
25240     SecItem_new_from_SECItem,
25241     cert_distnames_new_from_CERTDistNames,
25242     cert_distnames_as_CERTDistNames,
25243     _AddIntConstantWithLookup,
25244     _AddIntConstantAlias,
25245     format_from_lines,
25246     line_fmt_tuple,
25247     obj_sprintf,
25248     obj_to_hex,
25249     raw_data_to_hex,
25250     fmt_label,
25251     timestamp_to_DateTime
25252 };
25253 
25254 /* ============================== Module Construction ============================= */
25255 
25256 PyDoc_STRVAR(module_doc,
25257 "This module implements the NSS functions\n\
25258 \n\
25259 ");
25260 
25261 #if PY_MAJOR_VERSION >= 3
25262 
25263 static struct PyModuleDef module_def = {
25264     PyModuleDef_HEAD_INIT,
25265     NSS_NSS_MODULE_NAME,        /* m_name */
25266     module_doc,                 /* m_doc */
25267     -1,                         /* m_size */
25268     module_methods,             /* m_methods */
25269     NULL,                       /* m_reload */
25270     NULL,                       /* m_traverse */
25271     NULL,                       /* m_clear */
25272     NULL                        /* m_free */
25273 };
25274 
25275 #else /* PY_MAOR_VERSION < 3 */
25276 #endif /* PY_MAJOR_VERSION */
25277 
MOD_INIT(nss)25278 MOD_INIT(nss)
25279 {
25280     PyObject *m;
25281 
25282     if (import_nspr_error_c_api() < 0) {
25283         return MOD_ERROR_VAL;
25284     }
25285 
25286     PyDateTime_IMPORT;
25287 
25288 #if PY_MAJOR_VERSION >= 3
25289     m = PyModule_Create(&module_def);
25290 #else
25291     m = Py_InitModule3(NSS_NSS_MODULE_NAME, module_methods, module_doc);
25292 #endif
25293 
25294     if (m == NULL) {
25295         return MOD_ERROR_VAL;
25296     }
25297 
25298     if ((empty_tuple = PyTuple_New(0)) == NULL) {
25299         return MOD_ERROR_VAL;
25300     }
25301     Py_INCREF(empty_tuple);
25302 
25303     if ((py_empty_string = PyUnicode_FromString("")) == NULL) {
25304         return MOD_ERROR_VAL;
25305     }
25306     Py_INCREF(py_empty_string);
25307 
25308 
25309     TYPE_READY(SecItemType);
25310     TYPE_READY(AlgorithmIDType);
25311     TYPE_READY(RSAGenParamsType);
25312     TYPE_READY(KEYPQGParamsType);
25313     TYPE_READY(RSAPublicKeyType);
25314     TYPE_READY(DSAPublicKeyType);
25315     TYPE_READY(SignedDataType);
25316     TYPE_READY(PublicKeyType);
25317     TYPE_READY(SubjectPublicKeyInfoType);
25318     TYPE_READY(CertDBType);
25319     TYPE_READY(CertificateExtensionType);
25320     TYPE_READY(CertificateType);
25321     TYPE_READY(PrivateKeyType);
25322     TYPE_READY(SignedCRLType);
25323     TYPE_READY(PK11SlotType);
25324     TYPE_READY(PK11SymKeyType);
25325     TYPE_READY(PK11ContextType);
25326     TYPE_READY(CRLDistributionPtType);
25327     TYPE_READY(CRLDistributionPtsType);
25328     TYPE_READY(AuthorityInfoAccessType);
25329     TYPE_READY(AuthorityInfoAccessesType);
25330     TYPE_READY(AVAType);
25331     TYPE_READY(RDNType);
25332     TYPE_READY(DNType);
25333     TYPE_READY(GeneralNameType);
25334     TYPE_READY(AuthKeyIDType);
25335     TYPE_READY(BasicConstraintsType);
25336     TYPE_READY(CertAttributeType);
25337     TYPE_READY(CertificateRequestType);
25338     TYPE_READY(InitParametersType);
25339     TYPE_READY(InitContextType);
25340     TYPE_READY(PKCS12DecodeItemType);
25341     TYPE_READY(PKCS12DecoderType);
25342     TYPE_READY(CertVerifyLogNodeType);
25343     TYPE_READY(CertVerifyLogType);
25344 
25345     /* Export C API */
25346     if (PyModule_AddObject(m, "_C_API",
25347                            PyCapsule_New((void *)&nspr_nss_c_api, "_C_API", NULL)) != 0) {
25348         return MOD_ERROR_VAL;
25349     }
25350 
25351     AddIntConstant(OCTETS_PER_LINE_DEFAULT);
25352     PyModule_AddStringMacro(m, HEX_SEPARATOR_DEFAULT);
25353 
25354     AddIntConstant(AsObject);
25355     AddIntConstant(AsString);
25356     AddIntConstant(AsTypeString);
25357     AddIntConstant(AsTypeEnum);
25358     AddIntConstant(AsLabeledString);
25359     AddIntConstant(AsEnum);
25360     AddIntConstant(AsEnumName);
25361     AddIntConstant(AsEnumDescription);
25362     AddIntConstant(AsIndex);
25363     AddIntConstant(AsDottedDecimal);
25364 
25365     AddIntConstant(generalName);
25366     AddIntConstant(relativeDistinguishedName);
25367 
25368     AddIntConstant(PK11CertListUnique);
25369     AddIntConstant(PK11CertListUser);
25370     AddIntConstant(PK11CertListRootUnique);
25371     AddIntConstant(PK11CertListCA);
25372     AddIntConstant(PK11CertListCAUnique);
25373     AddIntConstant(PK11CertListUserUnique);
25374     AddIntConstant(PK11CertListAll);
25375 
25376     AddIntConstant(certUsageSSLClient);
25377     AddIntConstant(certUsageSSLServer);
25378     AddIntConstant(certUsageSSLServerWithStepUp);
25379     AddIntConstant(certUsageSSLCA);
25380     AddIntConstant(certUsageEmailSigner);
25381     AddIntConstant(certUsageEmailRecipient);
25382     AddIntConstant(certUsageObjectSigner);
25383     AddIntConstant(certUsageUserCertImport);
25384     AddIntConstant(certUsageVerifyCA);
25385     AddIntConstant(certUsageProtectedObjectSigner);
25386     AddIntConstant(certUsageStatusResponder);
25387     AddIntConstant(certUsageAnyCA);
25388 
25389     AddIntConstant(certificateUsageCheckAllUsages);
25390     AddIntConstant(certificateUsageSSLClient);
25391     AddIntConstant(certificateUsageSSLServer);
25392     AddIntConstant(certificateUsageSSLServerWithStepUp);
25393     AddIntConstant(certificateUsageSSLCA);
25394     AddIntConstant(certificateUsageEmailSigner);
25395     AddIntConstant(certificateUsageEmailRecipient);
25396     AddIntConstant(certificateUsageObjectSigner);
25397     AddIntConstant(certificateUsageUserCertImport);
25398     AddIntConstant(certificateUsageVerifyCA);
25399     AddIntConstant(certificateUsageProtectedObjectSigner);
25400     AddIntConstant(certificateUsageStatusResponder);
25401     AddIntConstant(certificateUsageAnyCA);
25402 
25403     AddIntConstant(NSS_INIT_READONLY);
25404     AddIntConstant(NSS_INIT_NOCERTDB);
25405     AddIntConstant(NSS_INIT_NOMODDB);
25406     AddIntConstant(NSS_INIT_FORCEOPEN);
25407     AddIntConstant(NSS_INIT_NOROOTINIT);
25408     AddIntConstant(NSS_INIT_OPTIMIZESPACE);
25409     AddIntConstant(NSS_INIT_PK11THREADSAFE);
25410     AddIntConstant(NSS_INIT_PK11RELOAD);
25411     AddIntConstant(NSS_INIT_NOPK11FINALIZE);
25412     AddIntConstant(NSS_INIT_RESERVED);
25413     AddIntConstant(NSS_INIT_COOPERATE);
25414 
25415     AddIntConstant(ssl_kea_null);
25416     AddIntConstant(ssl_kea_rsa);
25417     AddIntConstant(ssl_kea_dh);
25418     AddIntConstant(ssl_kea_fortezza);
25419     AddIntConstant(ssl_kea_ecdh);
25420 
25421     AddIntConstant(nullKey);
25422     AddIntConstant(rsaKey);
25423     AddIntConstant(dsaKey);
25424     AddIntConstant(fortezzaKey);
25425     AddIntConstant(dhKey);
25426     AddIntConstant(keaKey);
25427     AddIntConstant(ecKey);
25428 
25429     AddIntConstant(SEC_CERT_NICKNAMES_ALL);
25430     AddIntConstant(SEC_CERT_NICKNAMES_USER);
25431     AddIntConstant(SEC_CERT_NICKNAMES_SERVER);
25432     AddIntConstant(SEC_CERT_NICKNAMES_CA);
25433 
25434     AddIntConstant(SEC_CRL_TYPE);
25435     AddIntConstant(SEC_KRL_TYPE);
25436 
25437     AddIntConstant(CRL_DECODE_DEFAULT_OPTIONS);
25438     AddIntConstant(CRL_DECODE_DONT_COPY_DER);
25439     AddIntConstant(CRL_DECODE_SKIP_ENTRIES);
25440     AddIntConstant(CRL_DECODE_KEEP_BAD_CRL);
25441     AddIntConstant(CRL_DECODE_ADOPT_HEAP_DER);
25442 
25443     AddIntConstant(CRL_IMPORT_DEFAULT_OPTIONS);
25444     AddIntConstant(CRL_IMPORT_BYPASS_CHECKS);
25445 
25446 
25447     AddIntConstant(secCertTimeValid);
25448     AddIntConstant(secCertTimeExpired);
25449     AddIntConstant(secCertTimeNotValidYet);
25450 
25451     AddIntConstant(KU_DIGITAL_SIGNATURE);
25452     AddIntConstant(KU_NON_REPUDIATION);
25453     AddIntConstant(KU_KEY_ENCIPHERMENT);
25454     AddIntConstant(KU_DATA_ENCIPHERMENT);
25455     AddIntConstant(KU_KEY_AGREEMENT);
25456     AddIntConstant(KU_KEY_CERT_SIGN);
25457     AddIntConstant(KU_CRL_SIGN);
25458     AddIntConstant(KU_ENCIPHER_ONLY);
25459     AddIntConstant(KU_ALL);
25460     AddIntConstant(KU_DIGITAL_SIGNATURE_OR_NON_REPUDIATION);
25461     AddIntConstant(KU_KEY_AGREEMENT_OR_ENCIPHERMENT);
25462     AddIntConstant(KU_NS_GOVT_APPROVED);
25463 
25464 #if (NSS_VMAJOR > 3) || (NSS_VMAJOR == 3 && NSS_VMINOR >= 13)
25465     AddIntConstant(CERTDB_TERMINAL_RECORD);
25466 #else
25467     AddIntConstant(CERTDB_VALID_PEER);
25468 #endif
25469     AddIntConstant(CERTDB_TRUSTED);
25470     AddIntConstant(CERTDB_SEND_WARN);
25471     AddIntConstant(CERTDB_VALID_CA);
25472     AddIntConstant(CERTDB_TRUSTED_CA);
25473     AddIntConstant(CERTDB_NS_TRUSTED_CA);
25474     AddIntConstant(CERTDB_USER);
25475     AddIntConstant(CERTDB_TRUSTED_CLIENT_CA);
25476     AddIntConstant(CERTDB_GOVT_APPROVED_CA);
25477 
25478 
25479     /***************************************************************************
25480      * CRL Reason
25481      ***************************************************************************/
25482 
25483     if ((crl_reason_name_to_value = PyDict_New()) == NULL) {
25484         return MOD_ERROR_VAL;
25485     }
25486     if ((crl_reason_value_to_name = PyDict_New()) == NULL) {
25487         return MOD_ERROR_VAL;
25488     }
25489 
25490 #define ExportConstant(constant)                      \
25491 if (_AddIntConstantWithLookup(m, #constant, constant, \
25492     "crlEntry", crl_reason_name_to_value, crl_reason_value_to_name) < 0) return MOD_ERROR_VAL;
25493 
25494     ExportConstant(crlEntryReasonUnspecified);
25495     ExportConstant(crlEntryReasonKeyCompromise);
25496     ExportConstant(crlEntryReasonCaCompromise);
25497     ExportConstant(crlEntryReasonAffiliationChanged);
25498     ExportConstant(crlEntryReasonSuperseded);
25499     ExportConstant(crlEntryReasonCessationOfOperation);
25500     ExportConstant(crlEntryReasoncertificatedHold);
25501     ExportConstant(crlEntryReasonRemoveFromCRL);
25502     ExportConstant(crlEntryReasonPrivilegeWithdrawn);
25503     ExportConstant(crlEntryReasonAaCompromise);
25504 
25505 #undef ExportConstant
25506 
25507     /***************************************************************************
25508      * General Name Types
25509      ***************************************************************************/
25510 
25511     if ((general_name_name_to_value = PyDict_New()) == NULL) {
25512         return MOD_ERROR_VAL;
25513     }
25514     if ((general_name_value_to_name = PyDict_New()) == NULL) {
25515         return MOD_ERROR_VAL;
25516     }
25517 
25518 #define ExportConstant(constant)                      \
25519 if (_AddIntConstantWithLookup(m, #constant, constant, \
25520     "cert", general_name_name_to_value, general_name_value_to_name) < 0) return MOD_ERROR_VAL;
25521 
25522     ExportConstant(certOtherName);
25523     ExportConstant(certRFC822Name);
25524     ExportConstant(certDNSName);
25525     ExportConstant(certX400Address);
25526     ExportConstant(certDirectoryName);
25527     ExportConstant(certEDIPartyName);
25528     ExportConstant(certURI);
25529     ExportConstant(certIPAddress);
25530     ExportConstant(certRegisterID);
25531 
25532 #undef ExportConstant
25533 
25534     /***************************************************************************
25535      * Mechanism Types
25536      ***************************************************************************/
25537 
25538     if ((ckm_name_to_value = PyDict_New()) == NULL) {
25539         return MOD_ERROR_VAL;
25540     }
25541     if ((ckm_value_to_name = PyDict_New()) == NULL) {
25542         return MOD_ERROR_VAL;
25543     }
25544 
25545 #define ExportConstant(constant)                      \
25546 if (_AddIntConstantWithLookup(m, #constant, constant, \
25547     "CKM_", ckm_name_to_value, ckm_value_to_name) < 0) return MOD_ERROR_VAL;
25548 
25549     ExportConstant(CKM_RSA_PKCS_KEY_PAIR_GEN);
25550     ExportConstant(CKM_RSA_PKCS);
25551     ExportConstant(CKM_RSA_9796);
25552     ExportConstant(CKM_RSA_X_509);
25553 
25554     /* CKM_MD2_RSA_PKCS, CKM_MD5_RSA_PKCS, and CKM_SHA1_RSA_PKCS
25555      * are new for v2.0.  They are mechanisms which hash and sign */
25556     ExportConstant(CKM_MD2_RSA_PKCS);
25557     ExportConstant(CKM_MD5_RSA_PKCS);
25558     ExportConstant(CKM_SHA1_RSA_PKCS);
25559 
25560     /* CKM_RIPEMD128_RSA_PKCS, CKM_RIPEMD160_RSA_PKCS, and
25561      * CKM_RSA_PKCS_OAEP are new for v2.10 */
25562     ExportConstant(CKM_RIPEMD128_RSA_PKCS);
25563     ExportConstant(CKM_RIPEMD160_RSA_PKCS);
25564     ExportConstant(CKM_RSA_PKCS_OAEP);
25565 
25566     /* CKM_RSA_X9_31_KEY_PAIR_GEN, CKM_RSA_X9_31, CKM_SHA1_RSA_X9_31,
25567      * CKM_RSA_PKCS_PSS, and CKM_SHA1_RSA_PKCS_PSS are new for v2.11 */
25568     ExportConstant(CKM_RSA_X9_31_KEY_PAIR_GEN);
25569     ExportConstant(CKM_RSA_X9_31);
25570     ExportConstant(CKM_SHA1_RSA_X9_31);
25571     ExportConstant(CKM_RSA_PKCS_PSS);
25572     ExportConstant(CKM_SHA1_RSA_PKCS_PSS);
25573 
25574     ExportConstant(CKM_DSA_KEY_PAIR_GEN);
25575     ExportConstant(CKM_DSA);
25576     ExportConstant(CKM_DSA_SHA1);
25577     ExportConstant(CKM_DH_PKCS_KEY_PAIR_GEN);
25578     ExportConstant(CKM_DH_PKCS_DERIVE);
25579 
25580     /* CKM_X9_42_DH_KEY_PAIR_GEN, CKM_X9_42_DH_DERIVE,
25581      * CKM_X9_42_DH_HYBRID_DERIVE, and CKM_X9_42_MQV_DERIVE are new for
25582      * v2.11 */
25583     ExportConstant(CKM_X9_42_DH_KEY_PAIR_GEN);
25584     ExportConstant(CKM_X9_42_DH_DERIVE);
25585     ExportConstant(CKM_X9_42_DH_HYBRID_DERIVE);
25586     ExportConstant(CKM_X9_42_MQV_DERIVE);
25587 
25588     /* CKM_SHA256/384/512 are new for v2.20 */
25589     ExportConstant(CKM_SHA256_RSA_PKCS);
25590     ExportConstant(CKM_SHA384_RSA_PKCS);
25591     ExportConstant(CKM_SHA512_RSA_PKCS);
25592     ExportConstant(CKM_SHA256_RSA_PKCS_PSS);
25593     ExportConstant(CKM_SHA384_RSA_PKCS_PSS);
25594     ExportConstant(CKM_SHA512_RSA_PKCS_PSS);
25595 
25596     /* CKM_SHA224 new for v2.20 amendment 3 */
25597     ExportConstant(CKM_SHA224_RSA_PKCS);
25598     ExportConstant(CKM_SHA224_RSA_PKCS_PSS);
25599 
25600     ExportConstant(CKM_RC2_KEY_GEN);
25601     ExportConstant(CKM_RC2_ECB);
25602     ExportConstant(CKM_RC2_CBC);
25603     ExportConstant(CKM_RC2_MAC);
25604 
25605     /* CKM_RC2_MAC_GENERAL and CKM_RC2_CBC_PAD are new for v2.0 */
25606     ExportConstant(CKM_RC2_MAC_GENERAL);
25607     ExportConstant(CKM_RC2_CBC_PAD);
25608 
25609     ExportConstant(CKM_RC4_KEY_GEN);
25610     ExportConstant(CKM_RC4);
25611     ExportConstant(CKM_DES_KEY_GEN);
25612     ExportConstant(CKM_DES_ECB);
25613     ExportConstant(CKM_DES_CBC);
25614     ExportConstant(CKM_DES_MAC);
25615 
25616     /* CKM_DES_MAC_GENERAL and CKM_DES_CBC_PAD are new for v2.0 */
25617     ExportConstant(CKM_DES_MAC_GENERAL);
25618     ExportConstant(CKM_DES_CBC_PAD);
25619 
25620     ExportConstant(CKM_DES2_KEY_GEN);
25621     ExportConstant(CKM_DES3_KEY_GEN);
25622     ExportConstant(CKM_DES3_ECB);
25623     ExportConstant(CKM_DES3_CBC);
25624     ExportConstant(CKM_DES3_MAC);
25625 
25626     /* CKM_DES3_MAC_GENERAL, CKM_DES3_CBC_PAD, CKM_CDMF_KEY_GEN,
25627      * CKM_CDMF_ECB, CKM_CDMF_CBC, CKM_CDMF_MAC,
25628      * CKM_CDMF_MAC_GENERAL, and CKM_CDMF_CBC_PAD are new for v2.0 */
25629     ExportConstant(CKM_DES3_MAC_GENERAL);
25630     ExportConstant(CKM_DES3_CBC_PAD);
25631     ExportConstant(CKM_CDMF_KEY_GEN);
25632     ExportConstant(CKM_CDMF_ECB);
25633     ExportConstant(CKM_CDMF_CBC);
25634     ExportConstant(CKM_CDMF_MAC);
25635     ExportConstant(CKM_CDMF_MAC_GENERAL);
25636     ExportConstant(CKM_CDMF_CBC_PAD);
25637 
25638     /* the following four DES mechanisms are new for v2.20 */
25639     ExportConstant(CKM_DES_OFB64);
25640     ExportConstant(CKM_DES_OFB8);
25641     ExportConstant(CKM_DES_CFB64);
25642     ExportConstant(CKM_DES_CFB8);
25643 
25644     ExportConstant(CKM_MD2);
25645 
25646     /* CKM_MD2_HMAC and CKM_MD2_HMAC_GENERAL are new for v2.0 */
25647     ExportConstant(CKM_MD2_HMAC);
25648     ExportConstant(CKM_MD2_HMAC_GENERAL);
25649 
25650     ExportConstant(CKM_MD5);
25651 
25652     /* CKM_MD5_HMAC and CKM_MD5_HMAC_GENERAL are new for v2.0 */
25653     ExportConstant(CKM_MD5_HMAC);
25654     ExportConstant(CKM_MD5_HMAC_GENERAL);
25655 
25656     ExportConstant(CKM_SHA_1);
25657 
25658     /* CKM_SHA_1_HMAC and CKM_SHA_1_HMAC_GENERAL are new for v2.0 */
25659     ExportConstant(CKM_SHA_1_HMAC);
25660     ExportConstant(CKM_SHA_1_HMAC_GENERAL);
25661 
25662     /* CKM_RIPEMD128, CKM_RIPEMD128_HMAC,
25663      * CKM_RIPEMD128_HMAC_GENERAL, CKM_RIPEMD160, CKM_RIPEMD160_HMAC,
25664      * and CKM_RIPEMD160_HMAC_GENERAL are new for v2.10 */
25665     ExportConstant(CKM_RIPEMD128);
25666     ExportConstant(CKM_RIPEMD128_HMAC);
25667     ExportConstant(CKM_RIPEMD128_HMAC_GENERAL);
25668     ExportConstant(CKM_RIPEMD160);
25669     ExportConstant(CKM_RIPEMD160_HMAC);
25670     ExportConstant(CKM_RIPEMD160_HMAC_GENERAL);
25671 
25672     /* CKM_SHA256/384/512 are new for v2.20 */
25673     ExportConstant(CKM_SHA256);
25674     ExportConstant(CKM_SHA256_HMAC);
25675     ExportConstant(CKM_SHA256_HMAC_GENERAL);
25676     ExportConstant(CKM_SHA384);
25677     ExportConstant(CKM_SHA384_HMAC);
25678     ExportConstant(CKM_SHA384_HMAC_GENERAL);
25679     ExportConstant(CKM_SHA512);
25680     ExportConstant(CKM_SHA512_HMAC);
25681     ExportConstant(CKM_SHA512_HMAC_GENERAL);
25682 
25683     /* CKM_SHA224 new for v2.20 amendment 3 */
25684     ExportConstant(CKM_SHA224);
25685     ExportConstant(CKM_SHA224_HMAC);
25686     ExportConstant(CKM_SHA224_HMAC_GENERAL);
25687 
25688     /* All of the following mechanisms are new for v2.0 */
25689     /* Note that CAST128 and CAST5 are the same algorithm */
25690     ExportConstant(CKM_CAST_KEY_GEN);
25691     ExportConstant(CKM_CAST_ECB);
25692     ExportConstant(CKM_CAST_CBC);
25693     ExportConstant(CKM_CAST_MAC);
25694     ExportConstant(CKM_CAST_MAC_GENERAL);
25695     ExportConstant(CKM_CAST_CBC_PAD);
25696     ExportConstant(CKM_CAST3_KEY_GEN);
25697     ExportConstant(CKM_CAST3_ECB);
25698     ExportConstant(CKM_CAST3_CBC);
25699     ExportConstant(CKM_CAST3_MAC);
25700     ExportConstant(CKM_CAST3_MAC_GENERAL);
25701     ExportConstant(CKM_CAST3_CBC_PAD);
25702     ExportConstant(CKM_CAST5_KEY_GEN);
25703     ExportConstant(CKM_CAST128_KEY_GEN);
25704     ExportConstant(CKM_CAST5_ECB);
25705     ExportConstant(CKM_CAST128_ECB);
25706     ExportConstant(CKM_CAST5_CBC);
25707     ExportConstant(CKM_CAST128_CBC);
25708     ExportConstant(CKM_CAST5_MAC);
25709     ExportConstant(CKM_CAST128_MAC);
25710     ExportConstant(CKM_CAST5_MAC_GENERAL);
25711     ExportConstant(CKM_CAST128_MAC_GENERAL);
25712     ExportConstant(CKM_CAST5_CBC_PAD);
25713     ExportConstant(CKM_CAST128_CBC_PAD);
25714     ExportConstant(CKM_RC5_KEY_GEN);
25715     ExportConstant(CKM_RC5_ECB);
25716     ExportConstant(CKM_RC5_CBC);
25717     ExportConstant(CKM_RC5_MAC);
25718     ExportConstant(CKM_RC5_MAC_GENERAL);
25719     ExportConstant(CKM_RC5_CBC_PAD);
25720     ExportConstant(CKM_IDEA_KEY_GEN);
25721     ExportConstant(CKM_IDEA_ECB);
25722     ExportConstant(CKM_IDEA_CBC);
25723     ExportConstant(CKM_IDEA_MAC);
25724     ExportConstant(CKM_IDEA_MAC_GENERAL);
25725     ExportConstant(CKM_IDEA_CBC_PAD);
25726     ExportConstant(CKM_GENERIC_SECRET_KEY_GEN);
25727     ExportConstant(CKM_CONCATENATE_BASE_AND_KEY);
25728     ExportConstant(CKM_CONCATENATE_BASE_AND_DATA);
25729     ExportConstant(CKM_CONCATENATE_DATA_AND_BASE);
25730     ExportConstant(CKM_XOR_BASE_AND_DATA);
25731     ExportConstant(CKM_EXTRACT_KEY_FROM_KEY);
25732     ExportConstant(CKM_SSL3_PRE_MASTER_KEY_GEN);
25733     ExportConstant(CKM_SSL3_MASTER_KEY_DERIVE);
25734     ExportConstant(CKM_SSL3_KEY_AND_MAC_DERIVE);
25735 
25736     /* CKM_SSL3_MASTER_KEY_DERIVE_DH, CKM_TLS_PRE_MASTER_KEY_GEN,
25737      * CKM_TLS_MASTER_KEY_DERIVE, CKM_TLS_KEY_AND_MAC_DERIVE, and
25738      * CKM_TLS_MASTER_KEY_DERIVE_DH are new for v2.11 */
25739     ExportConstant(CKM_SSL3_MASTER_KEY_DERIVE_DH);
25740     ExportConstant(CKM_TLS_PRE_MASTER_KEY_GEN);
25741     ExportConstant(CKM_TLS_MASTER_KEY_DERIVE);
25742     ExportConstant(CKM_TLS_KEY_AND_MAC_DERIVE);
25743     ExportConstant(CKM_TLS_MASTER_KEY_DERIVE_DH);
25744 
25745     /* CKM_TLS_PRF is new for v2.20 */
25746     ExportConstant(CKM_TLS_PRF);
25747 
25748     ExportConstant(CKM_SSL3_MD5_MAC);
25749     ExportConstant(CKM_SSL3_SHA1_MAC);
25750     ExportConstant(CKM_MD5_KEY_DERIVATION);
25751     ExportConstant(CKM_MD2_KEY_DERIVATION);
25752     ExportConstant(CKM_SHA1_KEY_DERIVATION);
25753 
25754     /* CKM_SHA256/384/512 are new for v2.20 */
25755     ExportConstant(CKM_SHA256_KEY_DERIVATION);
25756     ExportConstant(CKM_SHA384_KEY_DERIVATION);
25757     ExportConstant(CKM_SHA512_KEY_DERIVATION);
25758 
25759     /* CKM_SHA224 new for v2.20 amendment 3 */
25760     ExportConstant(CKM_SHA224_KEY_DERIVATION);
25761 
25762     ExportConstant(CKM_PBE_MD2_DES_CBC);
25763     ExportConstant(CKM_PBE_MD5_DES_CBC);
25764     ExportConstant(CKM_PBE_MD5_CAST_CBC);
25765     ExportConstant(CKM_PBE_MD5_CAST3_CBC);
25766     ExportConstant(CKM_PBE_MD5_CAST5_CBC);
25767     ExportConstant(CKM_PBE_MD5_CAST128_CBC);
25768     ExportConstant(CKM_PBE_SHA1_CAST5_CBC);
25769     ExportConstant(CKM_PBE_SHA1_CAST128_CBC);
25770     ExportConstant(CKM_PBE_SHA1_RC4_128);
25771     ExportConstant(CKM_PBE_SHA1_RC4_40);
25772     ExportConstant(CKM_PBE_SHA1_DES3_EDE_CBC);
25773     ExportConstant(CKM_PBE_SHA1_DES2_EDE_CBC);
25774     ExportConstant(CKM_PBE_SHA1_RC2_128_CBC);
25775     ExportConstant(CKM_PBE_SHA1_RC2_40_CBC);
25776 
25777     /* CKM_PKCS5_PBKD2 is new for v2.10 */
25778     ExportConstant(CKM_PKCS5_PBKD2);
25779 
25780     ExportConstant(CKM_PBA_SHA1_WITH_SHA1_HMAC);
25781 
25782     /* WTLS mechanisms are new for v2.20 */
25783     ExportConstant(CKM_WTLS_PRE_MASTER_KEY_GEN);
25784     ExportConstant(CKM_WTLS_MASTER_KEY_DERIVE);
25785     ExportConstant(CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC);
25786     ExportConstant(CKM_WTLS_PRF);
25787     ExportConstant(CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE);
25788     ExportConstant(CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE);
25789 
25790     ExportConstant(CKM_KEY_WRAP_LYNKS);
25791     ExportConstant(CKM_KEY_WRAP_SET_OAEP);
25792 
25793     /* CKM_CMS_SIG is new for v2.20 */
25794     ExportConstant(CKM_CMS_SIG);
25795 
25796     /* Fortezza mechanisms */
25797     ExportConstant(CKM_SKIPJACK_KEY_GEN);
25798     ExportConstant(CKM_SKIPJACK_ECB64);
25799     ExportConstant(CKM_SKIPJACK_CBC64);
25800     ExportConstant(CKM_SKIPJACK_OFB64);
25801     ExportConstant(CKM_SKIPJACK_CFB64);
25802     ExportConstant(CKM_SKIPJACK_CFB32);
25803     ExportConstant(CKM_SKIPJACK_CFB16);
25804     ExportConstant(CKM_SKIPJACK_CFB8);
25805     ExportConstant(CKM_SKIPJACK_WRAP);
25806     ExportConstant(CKM_SKIPJACK_PRIVATE_WRAP);
25807     ExportConstant(CKM_SKIPJACK_RELAYX);
25808     ExportConstant(CKM_KEA_KEY_PAIR_GEN);
25809     ExportConstant(CKM_KEA_KEY_DERIVE);
25810     ExportConstant(CKM_FORTEZZA_TIMESTAMP);
25811     ExportConstant(CKM_BATON_KEY_GEN);
25812     ExportConstant(CKM_BATON_ECB128);
25813     ExportConstant(CKM_BATON_ECB96);
25814     ExportConstant(CKM_BATON_CBC128);
25815     ExportConstant(CKM_BATON_COUNTER);
25816     ExportConstant(CKM_BATON_SHUFFLE);
25817     ExportConstant(CKM_BATON_WRAP);
25818 
25819     /* CKM_ECDSA_KEY_PAIR_GEN is deprecated in v2.11,
25820      * CKM_EC_KEY_PAIR_GEN is preferred */
25821     ExportConstant(CKM_ECDSA_KEY_PAIR_GEN);
25822     ExportConstant(CKM_EC_KEY_PAIR_GEN);
25823 
25824     ExportConstant(CKM_ECDSA);
25825     ExportConstant(CKM_ECDSA_SHA1);
25826 
25827     /* CKM_ECDH1_DERIVE, CKM_ECDH1_COFACTOR_DERIVE, and CKM_ECMQV_DERIVE
25828      * are new for v2.11 */
25829     ExportConstant(CKM_ECDH1_DERIVE);
25830     ExportConstant(CKM_ECDH1_COFACTOR_DERIVE);
25831     ExportConstant(CKM_ECMQV_DERIVE);
25832 
25833     ExportConstant(CKM_JUNIPER_KEY_GEN);
25834     ExportConstant(CKM_JUNIPER_ECB128);
25835     ExportConstant(CKM_JUNIPER_CBC128);
25836     ExportConstant(CKM_JUNIPER_COUNTER);
25837     ExportConstant(CKM_JUNIPER_SHUFFLE);
25838     ExportConstant(CKM_JUNIPER_WRAP);
25839     ExportConstant(CKM_FASTHASH);
25840 
25841     /* CKM_AES_KEY_GEN, CKM_AES_ECB, CKM_AES_CBC, CKM_AES_MAC,
25842      * CKM_AES_MAC_GENERAL, CKM_AES_CBC_PAD, CKM_DSA_PARAMETER_GEN,
25843      * CKM_DH_PKCS_PARAMETER_GEN, and CKM_X9_42_DH_PARAMETER_GEN are
25844      * new for v2.11 */
25845     ExportConstant(CKM_AES_KEY_GEN);
25846     ExportConstant(CKM_AES_ECB);
25847     ExportConstant(CKM_AES_CBC);
25848     ExportConstant(CKM_AES_MAC);
25849     ExportConstant(CKM_AES_MAC_GENERAL);
25850     ExportConstant(CKM_AES_CBC_PAD);
25851 
25852     /* BlowFish and TwoFish are new for v2.20 */
25853     ExportConstant(CKM_BLOWFISH_KEY_GEN);
25854     ExportConstant(CKM_BLOWFISH_CBC);
25855     ExportConstant(CKM_TWOFISH_KEY_GEN);
25856     ExportConstant(CKM_TWOFISH_CBC);
25857 
25858     /* Camellia is proposed for v2.20 Amendment 3 */
25859     ExportConstant(CKM_CAMELLIA_KEY_GEN);
25860     ExportConstant(CKM_CAMELLIA_ECB);
25861     ExportConstant(CKM_CAMELLIA_CBC);
25862     ExportConstant(CKM_CAMELLIA_MAC);
25863     ExportConstant(CKM_CAMELLIA_MAC_GENERAL);
25864     ExportConstant(CKM_CAMELLIA_CBC_PAD);
25865     ExportConstant(CKM_CAMELLIA_ECB_ENCRYPT_DATA);
25866     ExportConstant(CKM_CAMELLIA_CBC_ENCRYPT_DATA);
25867 
25868 #if defined(CKM_SEED_KEY_GEN)
25869     ExportConstant(CKM_SEED_KEY_GEN);
25870     ExportConstant(CKM_SEED_ECB);
25871     ExportConstant(CKM_SEED_CBC);
25872     ExportConstant(CKM_SEED_MAC);
25873     ExportConstant(CKM_SEED_MAC_GENERAL);
25874     ExportConstant(CKM_SEED_CBC_PAD);
25875     ExportConstant(CKM_SEED_ECB_ENCRYPT_DATA);
25876     ExportConstant(CKM_SEED_CBC_ENCRYPT_DATA);
25877 #endif
25878 
25879     /* CKM_xxx_ENCRYPT_DATA mechanisms are new for v2.20 */
25880     ExportConstant(CKM_DES_ECB_ENCRYPT_DATA);
25881     ExportConstant(CKM_DES_CBC_ENCRYPT_DATA);
25882     ExportConstant(CKM_DES3_ECB_ENCRYPT_DATA);
25883     ExportConstant(CKM_DES3_CBC_ENCRYPT_DATA);
25884     ExportConstant(CKM_AES_ECB_ENCRYPT_DATA);
25885     ExportConstant(CKM_AES_CBC_ENCRYPT_DATA);
25886 
25887     ExportConstant(CKM_DSA_PARAMETER_GEN);
25888     ExportConstant(CKM_DH_PKCS_PARAMETER_GEN);
25889     ExportConstant(CKM_X9_42_DH_PARAMETER_GEN);
25890 
25891 #undef ExportConstant
25892 
25893     /***************************************************************************
25894      * Attribute Types
25895      ***************************************************************************/
25896     if ((cka_name_to_value = PyDict_New()) == NULL) {
25897         return MOD_ERROR_VAL;
25898     }
25899     if ((cka_value_to_name = PyDict_New()) == NULL) {
25900         return MOD_ERROR_VAL;
25901     }
25902 
25903 #define ExportConstant(constant)                      \
25904 if (_AddIntConstantWithLookup(m, #constant, constant, \
25905     "CKA_", cka_name_to_value, cka_value_to_name) < 0) return MOD_ERROR_VAL;
25906 
25907     /* The following attribute types are defined: */
25908     ExportConstant(CKA_CLASS);
25909     ExportConstant(CKA_TOKEN);
25910     ExportConstant(CKA_PRIVATE);
25911     ExportConstant(CKA_LABEL);
25912     ExportConstant(CKA_APPLICATION);
25913     ExportConstant(CKA_VALUE);
25914 
25915     /* CKA_OBJECT_ID is new for v2.10 */
25916     ExportConstant(CKA_OBJECT_ID);
25917 
25918     ExportConstant(CKA_CERTIFICATE_TYPE);
25919     ExportConstant(CKA_ISSUER);
25920     ExportConstant(CKA_SERIAL_NUMBER);
25921 
25922     /* CKA_AC_ISSUER, CKA_OWNER, and CKA_ATTR_TYPES are new for v2.10 */
25923     ExportConstant(CKA_AC_ISSUER);
25924     ExportConstant(CKA_OWNER);
25925     ExportConstant(CKA_ATTR_TYPES);
25926 
25927     /* CKA_TRUSTED is new for v2.11 */
25928     ExportConstant(CKA_TRUSTED);
25929 
25930     /* CKA_CERTIFICATE_CATEGORY ...
25931      * CKA_CHECK_VALUE are new for v2.20 */
25932     ExportConstant(CKA_CERTIFICATE_CATEGORY);
25933     ExportConstant(CKA_JAVA_MIDP_SECURITY_DOMAIN);
25934     ExportConstant(CKA_URL);
25935     ExportConstant(CKA_HASH_OF_SUBJECT_PUBLIC_KEY);
25936     ExportConstant(CKA_HASH_OF_ISSUER_PUBLIC_KEY);
25937     ExportConstant(CKA_CHECK_VALUE);
25938 
25939     ExportConstant(CKA_KEY_TYPE);
25940     ExportConstant(CKA_SUBJECT);
25941     ExportConstant(CKA_ID);
25942     ExportConstant(CKA_SENSITIVE);
25943     ExportConstant(CKA_ENCRYPT);
25944     ExportConstant(CKA_DECRYPT);
25945     ExportConstant(CKA_WRAP);
25946     ExportConstant(CKA_UNWRAP);
25947     ExportConstant(CKA_SIGN);
25948     ExportConstant(CKA_SIGN_RECOVER);
25949     ExportConstant(CKA_VERIFY);
25950     ExportConstant(CKA_VERIFY_RECOVER);
25951     ExportConstant(CKA_DERIVE);
25952     ExportConstant(CKA_START_DATE);
25953     ExportConstant(CKA_END_DATE);
25954     ExportConstant(CKA_MODULUS);
25955     ExportConstant(CKA_MODULUS_BITS);
25956     ExportConstant(CKA_PUBLIC_EXPONENT);
25957     ExportConstant(CKA_PRIVATE_EXPONENT);
25958     ExportConstant(CKA_PRIME_1);
25959     ExportConstant(CKA_PRIME_2);
25960     ExportConstant(CKA_EXPONENT_1);
25961     ExportConstant(CKA_EXPONENT_2);
25962     ExportConstant(CKA_COEFFICIENT);
25963     ExportConstant(CKA_PRIME);
25964     ExportConstant(CKA_SUBPRIME);
25965     ExportConstant(CKA_BASE);
25966 
25967     /* CKA_PRIME_BITS and CKA_SUB_PRIME_BITS are new for v2.11 */
25968     ExportConstant(CKA_PRIME_BITS);
25969     ExportConstant(CKA_SUBPRIME_BITS);
25970     ExportConstant(CKA_SUB_PRIME_BITS);
25971     /* (To retain backwards-compatibility) */
25972 
25973     ExportConstant(CKA_VALUE_BITS);
25974     ExportConstant(CKA_VALUE_LEN);
25975 
25976     /* CKA_EXTRACTABLE, CKA_LOCAL, CKA_NEVER_EXTRACTABLE,
25977      * CKA_ALWAYS_SENSITIVE, CKA_MODIFIABLE, CKA_ECDSA_PARAMS,
25978      * and CKA_EC_POINT are new for v2.0 */
25979     ExportConstant(CKA_EXTRACTABLE);
25980     ExportConstant(CKA_LOCAL);
25981     ExportConstant(CKA_NEVER_EXTRACTABLE);
25982     ExportConstant(CKA_ALWAYS_SENSITIVE);
25983 
25984     /* CKA_KEY_GEN_MECHANISM is new for v2.11 */
25985     ExportConstant(CKA_KEY_GEN_MECHANISM);
25986 
25987     ExportConstant(CKA_MODIFIABLE);
25988 
25989     /* CKA_ECDSA_PARAMS is deprecated in v2.11,
25990      * CKA_EC_PARAMS is preferred. */
25991     ExportConstant(CKA_ECDSA_PARAMS);
25992     ExportConstant(CKA_EC_PARAMS);
25993 
25994     ExportConstant(CKA_EC_POINT);
25995 
25996     /* CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS,
25997      * are new for v2.10. Deprecated in v2.11 and onwards. */
25998     ExportConstant(CKA_SECONDARY_AUTH);
25999     ExportConstant(CKA_AUTH_PIN_FLAGS);
26000 
26001     /* CKA_ALWAYS_AUTHENTICATE ...
26002      * CKA_UNWRAP_TEMPLATE are new for v2.20 */
26003     ExportConstant(CKA_ALWAYS_AUTHENTICATE);
26004 
26005     ExportConstant(CKA_WRAP_WITH_TRUSTED);
26006     ExportConstant(CKA_WRAP_TEMPLATE);
26007     ExportConstant(CKA_UNWRAP_TEMPLATE);
26008 
26009     /* CKA_HW_FEATURE_TYPE, CKA_RESET_ON_INIT, and CKA_HAS_RESET
26010      * are new for v2.10 */
26011     ExportConstant(CKA_HW_FEATURE_TYPE);
26012     ExportConstant(CKA_RESET_ON_INIT);
26013     ExportConstant(CKA_HAS_RESET);
26014 
26015     /* The following attributes are new for v2.20 */
26016     ExportConstant(CKA_PIXEL_X);
26017     ExportConstant(CKA_PIXEL_Y);
26018     ExportConstant(CKA_RESOLUTION);
26019     ExportConstant(CKA_CHAR_ROWS);
26020     ExportConstant(CKA_CHAR_COLUMNS);
26021     ExportConstant(CKA_COLOR);
26022     ExportConstant(CKA_BITS_PER_PIXEL);
26023     ExportConstant(CKA_CHAR_SETS);
26024     ExportConstant(CKA_ENCODING_METHODS);
26025     ExportConstant(CKA_MIME_TYPES);
26026     ExportConstant(CKA_MECHANISM_TYPE);
26027     ExportConstant(CKA_REQUIRED_CMS_ATTRIBUTES);
26028     ExportConstant(CKA_DEFAULT_CMS_ATTRIBUTES);
26029     ExportConstant(CKA_SUPPORTED_CMS_ATTRIBUTES);
26030     ExportConstant(CKA_ALLOWED_MECHANISMS);
26031 
26032     ExportConstant(CKA_VENDOR_DEFINED);
26033 
26034 #undef ExportConstant
26035 
26036     /***************************************************************************
26037      * SEC OID TAGS
26038      ***************************************************************************/
26039 
26040     if ((sec_oid_name_to_value = PyDict_New()) == NULL) {
26041         return MOD_ERROR_VAL;
26042     }
26043     if ((sec_oid_value_to_name = PyDict_New()) == NULL) {
26044         return MOD_ERROR_VAL;
26045     }
26046 
26047 #define ExportConstant(constant)                      \
26048 if (_AddIntConstantWithLookup(m, #constant, constant, \
26049     "SEC_OID_", sec_oid_name_to_value, sec_oid_value_to_name) < 0) return MOD_ERROR_VAL;
26050 
26051     ExportConstant(SEC_OID_UNKNOWN);
26052     ExportConstant(SEC_OID_MD2);
26053     ExportConstant(SEC_OID_MD4);
26054     ExportConstant(SEC_OID_MD5);
26055     ExportConstant(SEC_OID_SHA1);
26056     ExportConstant(SEC_OID_RC2_CBC);
26057     ExportConstant(SEC_OID_RC4);
26058     ExportConstant(SEC_OID_DES_EDE3_CBC);
26059     ExportConstant(SEC_OID_RC5_CBC_PAD);
26060     ExportConstant(SEC_OID_DES_ECB);
26061     ExportConstant(SEC_OID_DES_CBC);
26062     ExportConstant(SEC_OID_DES_OFB);
26063     ExportConstant(SEC_OID_DES_CFB);
26064     ExportConstant(SEC_OID_DES_MAC);
26065     ExportConstant(SEC_OID_DES_EDE);
26066     ExportConstant(SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE);
26067     ExportConstant(SEC_OID_PKCS1_RSA_ENCRYPTION);
26068     ExportConstant(SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION);
26069     ExportConstant(SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION);
26070     ExportConstant(SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION);
26071     ExportConstant(SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION);
26072     ExportConstant(SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC);
26073     ExportConstant(SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC);
26074     ExportConstant(SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC);
26075     ExportConstant(SEC_OID_PKCS7);
26076     ExportConstant(SEC_OID_PKCS7_DATA);
26077     ExportConstant(SEC_OID_PKCS7_SIGNED_DATA);
26078     ExportConstant(SEC_OID_PKCS7_ENVELOPED_DATA);
26079     ExportConstant(SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA);
26080     ExportConstant(SEC_OID_PKCS7_DIGESTED_DATA);
26081     ExportConstant(SEC_OID_PKCS7_ENCRYPTED_DATA);
26082     ExportConstant(SEC_OID_PKCS9_EMAIL_ADDRESS);
26083     ExportConstant(SEC_OID_PKCS9_UNSTRUCTURED_NAME);
26084     ExportConstant(SEC_OID_PKCS9_CONTENT_TYPE);
26085     ExportConstant(SEC_OID_PKCS9_MESSAGE_DIGEST);
26086     ExportConstant(SEC_OID_PKCS9_SIGNING_TIME);
26087     ExportConstant(SEC_OID_PKCS9_COUNTER_SIGNATURE);
26088     ExportConstant(SEC_OID_PKCS9_CHALLENGE_PASSWORD);
26089     ExportConstant(SEC_OID_PKCS9_UNSTRUCTURED_ADDRESS);
26090     ExportConstant(SEC_OID_PKCS9_EXTENDED_CERTIFICATE_ATTRIBUTES);
26091     ExportConstant(SEC_OID_PKCS9_SMIME_CAPABILITIES);
26092     ExportConstant(SEC_OID_AVA_COMMON_NAME);
26093     ExportConstant(SEC_OID_AVA_COUNTRY_NAME);
26094     ExportConstant(SEC_OID_AVA_LOCALITY);
26095     ExportConstant(SEC_OID_AVA_STATE_OR_PROVINCE);
26096     ExportConstant(SEC_OID_AVA_ORGANIZATION_NAME);
26097     ExportConstant(SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME);
26098     ExportConstant(SEC_OID_AVA_DN_QUALIFIER);
26099     ExportConstant(SEC_OID_AVA_DC);
26100 
26101     ExportConstant(SEC_OID_NS_TYPE_GIF);
26102     ExportConstant(SEC_OID_NS_TYPE_JPEG);
26103     ExportConstant(SEC_OID_NS_TYPE_URL);
26104     ExportConstant(SEC_OID_NS_TYPE_HTML);
26105     ExportConstant(SEC_OID_NS_TYPE_CERT_SEQUENCE);
26106     ExportConstant(SEC_OID_MISSI_KEA_DSS_OLD);
26107     ExportConstant(SEC_OID_MISSI_DSS_OLD);
26108     ExportConstant(SEC_OID_MISSI_KEA_DSS);
26109     ExportConstant(SEC_OID_MISSI_DSS);
26110     ExportConstant(SEC_OID_MISSI_KEA);
26111     ExportConstant(SEC_OID_MISSI_ALT_KEA);
26112 
26113     /* Netscape private certificate extensions */
26114     ExportConstant(SEC_OID_NS_CERT_EXT_NETSCAPE_OK);
26115     ExportConstant(SEC_OID_NS_CERT_EXT_ISSUER_LOGO);
26116     ExportConstant(SEC_OID_NS_CERT_EXT_SUBJECT_LOGO);
26117     ExportConstant(SEC_OID_NS_CERT_EXT_CERT_TYPE);
26118     ExportConstant(SEC_OID_NS_CERT_EXT_BASE_URL);
26119     ExportConstant(SEC_OID_NS_CERT_EXT_REVOCATION_URL);
26120     ExportConstant(SEC_OID_NS_CERT_EXT_CA_REVOCATION_URL);
26121     ExportConstant(SEC_OID_NS_CERT_EXT_CA_CRL_URL);
26122     ExportConstant(SEC_OID_NS_CERT_EXT_CA_CERT_URL);
26123     ExportConstant(SEC_OID_NS_CERT_EXT_CERT_RENEWAL_URL);
26124     ExportConstant(SEC_OID_NS_CERT_EXT_CA_POLICY_URL);
26125     ExportConstant(SEC_OID_NS_CERT_EXT_HOMEPAGE_URL);
26126     ExportConstant(SEC_OID_NS_CERT_EXT_ENTITY_LOGO);
26127     ExportConstant(SEC_OID_NS_CERT_EXT_USER_PICTURE);
26128     ExportConstant(SEC_OID_NS_CERT_EXT_SSL_SERVER_NAME);
26129     ExportConstant(SEC_OID_NS_CERT_EXT_COMMENT);
26130     ExportConstant(SEC_OID_NS_CERT_EXT_LOST_PASSWORD_URL);
26131     ExportConstant(SEC_OID_NS_CERT_EXT_CERT_RENEWAL_TIME);
26132     ExportConstant(SEC_OID_NS_KEY_USAGE_GOVT_APPROVED);
26133 
26134     /* x.509 v3 Extensions */
26135     ExportConstant(SEC_OID_X509_SUBJECT_DIRECTORY_ATTR);
26136     ExportConstant(SEC_OID_X509_SUBJECT_KEY_ID);
26137     ExportConstant(SEC_OID_X509_KEY_USAGE);
26138     ExportConstant(SEC_OID_X509_PRIVATE_KEY_USAGE_PERIOD);
26139     ExportConstant(SEC_OID_X509_SUBJECT_ALT_NAME);
26140     ExportConstant(SEC_OID_X509_ISSUER_ALT_NAME);
26141     ExportConstant(SEC_OID_X509_BASIC_CONSTRAINTS);
26142     ExportConstant(SEC_OID_X509_NAME_CONSTRAINTS);
26143     ExportConstant(SEC_OID_X509_CRL_DIST_POINTS);
26144     ExportConstant(SEC_OID_X509_CERTIFICATE_POLICIES);
26145     ExportConstant(SEC_OID_X509_POLICY_MAPPINGS);
26146     ExportConstant(SEC_OID_X509_POLICY_CONSTRAINTS);
26147     ExportConstant(SEC_OID_X509_AUTH_KEY_ID);
26148     ExportConstant(SEC_OID_X509_EXT_KEY_USAGE);
26149     ExportConstant(SEC_OID_X509_AUTH_INFO_ACCESS);
26150 
26151     ExportConstant(SEC_OID_X509_CRL_NUMBER);
26152     ExportConstant(SEC_OID_X509_REASON_CODE);
26153     ExportConstant(SEC_OID_X509_INVALID_DATE);
26154     /* End of x.509 v3 Extensions */
26155 
26156     ExportConstant(SEC_OID_X500_RSA_ENCRYPTION);
26157 
26158     /* alg 1485 additions */
26159     ExportConstant(SEC_OID_RFC1274_UID);
26160     ExportConstant(SEC_OID_RFC1274_MAIL);
26161 
26162     /* PKCS 12 additions */
26163     ExportConstant(SEC_OID_PKCS12);
26164     ExportConstant(SEC_OID_PKCS12_MODE_IDS);
26165     ExportConstant(SEC_OID_PKCS12_ESPVK_IDS);
26166     ExportConstant(SEC_OID_PKCS12_BAG_IDS);
26167     ExportConstant(SEC_OID_PKCS12_CERT_BAG_IDS);
26168     ExportConstant(SEC_OID_PKCS12_OIDS);
26169     ExportConstant(SEC_OID_PKCS12_PBE_IDS);
26170     ExportConstant(SEC_OID_PKCS12_SIGNATURE_IDS);
26171     ExportConstant(SEC_OID_PKCS12_ENVELOPING_IDS);
26172    /* SEC_OID_PKCS12_OFFLINE_TRANSPORT_MODE,
26173     SEC_OID_PKCS12_ONLINE_TRANSPORT_MODE, */
26174     ExportConstant(SEC_OID_PKCS12_PKCS8_KEY_SHROUDING);
26175     ExportConstant(SEC_OID_PKCS12_KEY_BAG_ID);
26176     ExportConstant(SEC_OID_PKCS12_CERT_AND_CRL_BAG_ID);
26177     ExportConstant(SEC_OID_PKCS12_SECRET_BAG_ID);
26178     ExportConstant(SEC_OID_PKCS12_X509_CERT_CRL_BAG);
26179     ExportConstant(SEC_OID_PKCS12_SDSI_CERT_BAG);
26180     ExportConstant(SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4);
26181     ExportConstant(SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4);
26182     ExportConstant(SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC);
26183     ExportConstant(SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC);
26184     ExportConstant(SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC);
26185     ExportConstant(SEC_OID_PKCS12_RSA_ENCRYPTION_WITH_128_BIT_RC4);
26186     ExportConstant(SEC_OID_PKCS12_RSA_ENCRYPTION_WITH_40_BIT_RC4);
26187     ExportConstant(SEC_OID_PKCS12_RSA_ENCRYPTION_WITH_TRIPLE_DES);
26188     ExportConstant(SEC_OID_PKCS12_RSA_SIGNATURE_WITH_SHA1_DIGEST);
26189     /* end of PKCS 12 additions */
26190 
26191     /* DSA signatures */
26192     ExportConstant(SEC_OID_ANSIX9_DSA_SIGNATURE);
26193     ExportConstant(SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST);
26194     ExportConstant(SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST);
26195 
26196     /* Verisign OIDs */
26197     ExportConstant(SEC_OID_VERISIGN_USER_NOTICES);
26198 
26199     /* PKIX OIDs */
26200     ExportConstant(SEC_OID_PKIX_CPS_POINTER_QUALIFIER);
26201     ExportConstant(SEC_OID_PKIX_USER_NOTICE_QUALIFIER);
26202     ExportConstant(SEC_OID_PKIX_OCSP);
26203     ExportConstant(SEC_OID_PKIX_OCSP_BASIC_RESPONSE);
26204     ExportConstant(SEC_OID_PKIX_OCSP_NONCE);
26205     ExportConstant(SEC_OID_PKIX_OCSP_CRL);
26206     ExportConstant(SEC_OID_PKIX_OCSP_RESPONSE);
26207     ExportConstant(SEC_OID_PKIX_OCSP_NO_CHECK);
26208     ExportConstant(SEC_OID_PKIX_OCSP_ARCHIVE_CUTOFF);
26209     ExportConstant(SEC_OID_PKIX_OCSP_SERVICE_LOCATOR);
26210     ExportConstant(SEC_OID_PKIX_REGCTRL_REGTOKEN);
26211     ExportConstant(SEC_OID_PKIX_REGCTRL_AUTHENTICATOR);
26212     ExportConstant(SEC_OID_PKIX_REGCTRL_PKIPUBINFO);
26213     ExportConstant(SEC_OID_PKIX_REGCTRL_PKI_ARCH_OPTIONS);
26214     ExportConstant(SEC_OID_PKIX_REGCTRL_OLD_CERT_ID);
26215     ExportConstant(SEC_OID_PKIX_REGCTRL_PROTOCOL_ENC_KEY);
26216     ExportConstant(SEC_OID_PKIX_REGINFO_UTF8_PAIRS);
26217     ExportConstant(SEC_OID_PKIX_REGINFO_CERT_REQUEST);
26218     ExportConstant(SEC_OID_EXT_KEY_USAGE_SERVER_AUTH);
26219     ExportConstant(SEC_OID_EXT_KEY_USAGE_CLIENT_AUTH);
26220     ExportConstant(SEC_OID_EXT_KEY_USAGE_CODE_SIGN);
26221     ExportConstant(SEC_OID_EXT_KEY_USAGE_EMAIL_PROTECT);
26222     ExportConstant(SEC_OID_EXT_KEY_USAGE_TIME_STAMP);
26223     ExportConstant(SEC_OID_OCSP_RESPONDER);
26224 
26225     /* Netscape Algorithm OIDs */
26226     ExportConstant(SEC_OID_NETSCAPE_SMIME_KEA);
26227 
26228     /* Skipjack OID -- ### mwelch temporary */
26229     ExportConstant(SEC_OID_FORTEZZA_SKIPJACK);
26230 
26231     /* PKCS 12 V2 oids */
26232     ExportConstant(SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4);
26233     ExportConstant(SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4);
26234     ExportConstant(SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC);
26235     ExportConstant(SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC);
26236     ExportConstant(SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC);
26237     ExportConstant(SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC);
26238     ExportConstant(SEC_OID_PKCS12_SAFE_CONTENTS_ID);
26239     ExportConstant(SEC_OID_PKCS12_PKCS8_SHROUDED_KEY_BAG_ID);
26240 
26241     ExportConstant(SEC_OID_PKCS12_V1_KEY_BAG_ID);
26242     ExportConstant(SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID);
26243     ExportConstant(SEC_OID_PKCS12_V1_CERT_BAG_ID);
26244     ExportConstant(SEC_OID_PKCS12_V1_CRL_BAG_ID);
26245     ExportConstant(SEC_OID_PKCS12_V1_SECRET_BAG_ID);
26246     ExportConstant(SEC_OID_PKCS12_V1_SAFE_CONTENTS_BAG_ID);
26247     ExportConstant(SEC_OID_PKCS9_X509_CERT);
26248     ExportConstant(SEC_OID_PKCS9_SDSI_CERT);
26249     ExportConstant(SEC_OID_PKCS9_X509_CRL);
26250     ExportConstant(SEC_OID_PKCS9_FRIENDLY_NAME);
26251     ExportConstant(SEC_OID_PKCS9_LOCAL_KEY_ID);
26252     ExportConstant(SEC_OID_BOGUS_KEY_USAGE);
26253 
26254     /*Diffe Helman OIDS */
26255     ExportConstant(SEC_OID_X942_DIFFIE_HELMAN_KEY);
26256 
26257     /* Netscape other name types */
26258     ExportConstant(SEC_OID_NETSCAPE_NICKNAME);
26259 
26260     /* Cert Server OIDS */
26261     ExportConstant(SEC_OID_NETSCAPE_RECOVERY_REQUEST);
26262 
26263     /* New PSM certificate management OIDs */
26264     ExportConstant(SEC_OID_CERT_RENEWAL_LOCATOR);
26265     ExportConstant(SEC_OID_NS_CERT_EXT_SCOPE_OF_USE);
26266 
26267     /* CMS (RFC2630) OIDs */
26268     ExportConstant(SEC_OID_CMS_EPHEMERAL_STATIC_DIFFIE_HELLMAN);
26269     ExportConstant(SEC_OID_CMS_3DES_KEY_WRAP);
26270     ExportConstant(SEC_OID_CMS_RC2_KEY_WRAP);
26271 
26272     /* SMIME attributes */
26273     ExportConstant(SEC_OID_SMIME_ENCRYPTION_KEY_PREFERENCE);
26274 
26275     /* AES OIDs */
26276     ExportConstant(SEC_OID_AES_128_ECB);
26277     ExportConstant(SEC_OID_AES_128_CBC);
26278     ExportConstant(SEC_OID_AES_192_ECB);
26279     ExportConstant(SEC_OID_AES_192_CBC);
26280     ExportConstant(SEC_OID_AES_256_ECB);
26281     ExportConstant(SEC_OID_AES_256_CBC);
26282 
26283     ExportConstant(SEC_OID_SDN702_DSA_SIGNATURE);
26284 
26285     ExportConstant(SEC_OID_MS_SMIME_ENCRYPTION_KEY_PREFERENCE);
26286 
26287     ExportConstant(SEC_OID_SHA256);
26288     ExportConstant(SEC_OID_SHA384);
26289     ExportConstant(SEC_OID_SHA512);
26290 
26291     ExportConstant(SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION);
26292     ExportConstant(SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION);
26293     ExportConstant(SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION);
26294 
26295     ExportConstant(SEC_OID_AES_128_KEY_WRAP);
26296     ExportConstant(SEC_OID_AES_192_KEY_WRAP);
26297     ExportConstant(SEC_OID_AES_256_KEY_WRAP);
26298 
26299     /* Elliptic Curve Cryptography (ECC) OIDs */
26300     ExportConstant(SEC_OID_ANSIX962_EC_PUBLIC_KEY);
26301     ExportConstant(SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE);
26302 
26303     ExportConstant(SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST);
26304 
26305     /* ANSI X9.62 named elliptic curves (prime field) */
26306     ExportConstant(SEC_OID_ANSIX962_EC_PRIME192V1);
26307     ExportConstant(SEC_OID_ANSIX962_EC_PRIME192V2);
26308     ExportConstant(SEC_OID_ANSIX962_EC_PRIME192V3);
26309     ExportConstant(SEC_OID_ANSIX962_EC_PRIME239V1);
26310     ExportConstant(SEC_OID_ANSIX962_EC_PRIME239V2);
26311     ExportConstant(SEC_OID_ANSIX962_EC_PRIME239V3);
26312     ExportConstant(SEC_OID_ANSIX962_EC_PRIME256V1);
26313 
26314     /* SECG named elliptic curves (prime field) */
26315     ExportConstant(SEC_OID_SECG_EC_SECP112R1);
26316     ExportConstant(SEC_OID_SECG_EC_SECP112R2);
26317     ExportConstant(SEC_OID_SECG_EC_SECP128R1);
26318     ExportConstant(SEC_OID_SECG_EC_SECP128R2);
26319     ExportConstant(SEC_OID_SECG_EC_SECP160K1);
26320     ExportConstant(SEC_OID_SECG_EC_SECP160R1);
26321     ExportConstant(SEC_OID_SECG_EC_SECP160R2);
26322     ExportConstant(SEC_OID_SECG_EC_SECP192K1);
26323     /* SEC_OID_SECG_EC_SECP192R1 is SEC_OID_ANSIX962_EC_PRIME192V1 */
26324     ExportConstant(SEC_OID_SECG_EC_SECP224K1);
26325     ExportConstant(SEC_OID_SECG_EC_SECP224R1);
26326     ExportConstant(SEC_OID_SECG_EC_SECP256K1);
26327     /* SEC_OID_SECG_EC_SECP256R1 is SEC_OID_ANSIX962_EC_PRIME256V1 */
26328     ExportConstant(SEC_OID_SECG_EC_SECP384R1);
26329     ExportConstant(SEC_OID_SECG_EC_SECP521R1);
26330 
26331     /* ANSI X9.62 named elliptic curves (characteristic two field) */
26332     ExportConstant(SEC_OID_ANSIX962_EC_C2PNB163V1);
26333     ExportConstant(SEC_OID_ANSIX962_EC_C2PNB163V2);
26334     ExportConstant(SEC_OID_ANSIX962_EC_C2PNB163V3);
26335     ExportConstant(SEC_OID_ANSIX962_EC_C2PNB176V1);
26336     ExportConstant(SEC_OID_ANSIX962_EC_C2TNB191V1);
26337     ExportConstant(SEC_OID_ANSIX962_EC_C2TNB191V2);
26338     ExportConstant(SEC_OID_ANSIX962_EC_C2TNB191V3);
26339     ExportConstant(SEC_OID_ANSIX962_EC_C2ONB191V4);
26340     ExportConstant(SEC_OID_ANSIX962_EC_C2ONB191V5);
26341     ExportConstant(SEC_OID_ANSIX962_EC_C2PNB208W1);
26342     ExportConstant(SEC_OID_ANSIX962_EC_C2TNB239V1);
26343     ExportConstant(SEC_OID_ANSIX962_EC_C2TNB239V2);
26344     ExportConstant(SEC_OID_ANSIX962_EC_C2TNB239V3);
26345     ExportConstant(SEC_OID_ANSIX962_EC_C2ONB239V4);
26346     ExportConstant(SEC_OID_ANSIX962_EC_C2ONB239V5);
26347     ExportConstant(SEC_OID_ANSIX962_EC_C2PNB272W1);
26348     ExportConstant(SEC_OID_ANSIX962_EC_C2PNB304W1);
26349     ExportConstant(SEC_OID_ANSIX962_EC_C2TNB359V1);
26350     ExportConstant(SEC_OID_ANSIX962_EC_C2PNB368W1);
26351     ExportConstant(SEC_OID_ANSIX962_EC_C2TNB431R1);
26352 
26353     /* SECG named elliptic curves (characteristic two field) */
26354     ExportConstant(SEC_OID_SECG_EC_SECT113R1);
26355     ExportConstant(SEC_OID_SECG_EC_SECT113R2);
26356     ExportConstant(SEC_OID_SECG_EC_SECT131R1);
26357     ExportConstant(SEC_OID_SECG_EC_SECT131R2);
26358     ExportConstant(SEC_OID_SECG_EC_SECT163K1);
26359     ExportConstant(SEC_OID_SECG_EC_SECT163R1);
26360     ExportConstant(SEC_OID_SECG_EC_SECT163R2);
26361     ExportConstant(SEC_OID_SECG_EC_SECT193R1);
26362     ExportConstant(SEC_OID_SECG_EC_SECT193R2);
26363     ExportConstant(SEC_OID_SECG_EC_SECT233K1);
26364     ExportConstant(SEC_OID_SECG_EC_SECT233R1);
26365     ExportConstant(SEC_OID_SECG_EC_SECT239K1);
26366     ExportConstant(SEC_OID_SECG_EC_SECT283K1);
26367     ExportConstant(SEC_OID_SECG_EC_SECT283R1);
26368     ExportConstant(SEC_OID_SECG_EC_SECT409K1);
26369     ExportConstant(SEC_OID_SECG_EC_SECT409R1);
26370     ExportConstant(SEC_OID_SECG_EC_SECT571K1);
26371     ExportConstant(SEC_OID_SECG_EC_SECT571R1);
26372 
26373     ExportConstant(SEC_OID_NETSCAPE_AOLSCREENNAME);
26374 
26375     ExportConstant(SEC_OID_AVA_SURNAME);
26376     ExportConstant(SEC_OID_AVA_SERIAL_NUMBER);
26377     ExportConstant(SEC_OID_AVA_STREET_ADDRESS);
26378     ExportConstant(SEC_OID_AVA_TITLE);
26379     ExportConstant(SEC_OID_AVA_POSTAL_ADDRESS);
26380     ExportConstant(SEC_OID_AVA_POSTAL_CODE);
26381     ExportConstant(SEC_OID_AVA_POST_OFFICE_BOX);
26382     ExportConstant(SEC_OID_AVA_GIVEN_NAME);
26383     ExportConstant(SEC_OID_AVA_INITIALS);
26384     ExportConstant(SEC_OID_AVA_GENERATION_QUALIFIER);
26385     ExportConstant(SEC_OID_AVA_HOUSE_IDENTIFIER);
26386     ExportConstant(SEC_OID_AVA_PSEUDONYM);
26387 
26388     /* More OIDs */
26389     ExportConstant(SEC_OID_PKIX_CA_ISSUERS);
26390     ExportConstant(SEC_OID_PKCS9_EXTENSION_REQUEST);
26391 
26392     /* new EC Signature oids */
26393     ExportConstant(SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST);
26394     ExportConstant(SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST);
26395     ExportConstant(SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE);
26396     ExportConstant(SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE);
26397     ExportConstant(SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE);
26398     ExportConstant(SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE);
26399 
26400     /* More id-ce and id-pe OIDs from RFC 3280 */
26401     ExportConstant(SEC_OID_X509_HOLD_INSTRUCTION_CODE);
26402     ExportConstant(SEC_OID_X509_DELTA_CRL_INDICATOR);
26403     ExportConstant(SEC_OID_X509_ISSUING_DISTRIBUTION_POINT);
26404     ExportConstant(SEC_OID_X509_CERT_ISSUER);
26405     ExportConstant(SEC_OID_X509_FRESHEST_CRL);
26406     ExportConstant(SEC_OID_X509_INHIBIT_ANY_POLICY);
26407     ExportConstant(SEC_OID_X509_SUBJECT_INFO_ACCESS);
26408 
26409     /* Camellia OIDs (RFC3657)*/
26410     ExportConstant(SEC_OID_CAMELLIA_128_CBC);
26411     ExportConstant(SEC_OID_CAMELLIA_192_CBC);
26412     ExportConstant(SEC_OID_CAMELLIA_256_CBC);
26413 
26414     /* PKCS 5 V2 OIDS */
26415     ExportConstant(SEC_OID_PKCS5_PBKDF2);
26416     ExportConstant(SEC_OID_PKCS5_PBES2);
26417     ExportConstant(SEC_OID_PKCS5_PBMAC1);
26418     ExportConstant(SEC_OID_HMAC_SHA1);
26419     ExportConstant(SEC_OID_HMAC_SHA224);
26420     ExportConstant(SEC_OID_HMAC_SHA256);
26421     ExportConstant(SEC_OID_HMAC_SHA384);
26422     ExportConstant(SEC_OID_HMAC_SHA512);
26423 
26424     ExportConstant(SEC_OID_PKIX_TIMESTAMPING);
26425     ExportConstant(SEC_OID_PKIX_CA_REPOSITORY);
26426 
26427     ExportConstant(SEC_OID_ISO_SHA1_WITH_RSA_SIGNATURE);
26428 
26429 #if defined(SEC_OID_SEED_CBC)
26430     ExportConstant(SEC_OID_SEED_CBC);
26431 #endif
26432 
26433 #if defined(SEC_OID_X509_ANY_POLICY)
26434     ExportConstant(SEC_OID_X509_ANY_POLICY);
26435 #endif
26436 
26437     ExportConstant(SEC_OID_SECG_EC_SECP192R1);
26438     ExportConstant(SEC_OID_SECG_EC_SECP256R1);
26439     ExportConstant(SEC_OID_PKCS12_KEY_USAGE);
26440 
26441 #undef ExportConstant
26442 
26443     /***************************************************************************
26444      * PK11Origin
26445      ***************************************************************************/
26446     AddIntConstant(PK11_OriginNULL);         /* There is not key, it's a null SymKey */
26447     AddIntConstant(PK11_OriginDerive);       /* Key was derived from some other key */
26448     AddIntConstant(PK11_OriginGenerated);    /* Key was generated (also PBE keys) */
26449     AddIntConstant(PK11_OriginFortezzaHack); /* Key was marked for fortezza hack */
26450     AddIntConstant(PK11_OriginUnwrap);       /* Key was unwrapped or decrypted */
26451 
26452     /***************************************************************************
26453      * PK11 Slot Disabled Reason
26454      ***************************************************************************/
26455 
26456     AddIntConstant(PK11_DIS_NONE);                 /* no reason */
26457     AddIntConstant(PK11_DIS_USER_SELECTED);        /* user disabled */
26458     AddIntConstant(PK11_DIS_COULD_NOT_INIT_TOKEN); /* could not initialize token */
26459     AddIntConstant(PK11_DIS_TOKEN_VERIFY_FAILED);  /* could not verify token */
26460     AddIntConstant(PK11_DIS_TOKEN_NOT_PRESENT);    /* token not present */
26461 
26462     /***************************************************************************
26463      * OCSP Failure Mode
26464      ***************************************************************************/
26465 
26466     AddIntConstant(ocspMode_FailureIsVerificationFailure);
26467     AddIntConstant(ocspMode_FailureIsNotAVerificationFailure);
26468 
26469     /***************************************************************************
26470      * PKCS12
26471      ***************************************************************************/
26472 
26473     if ((pkcs12_cipher_name_to_value = PyDict_New()) == NULL) {
26474         return MOD_ERROR_VAL;
26475     }
26476     if ((pkcs12_cipher_value_to_name = PyDict_New()) == NULL) {
26477         return MOD_ERROR_VAL;
26478     }
26479 
26480 #define ExportConstant(constant)                      \
26481 if (_AddIntConstantWithLookup(m, #constant, constant, \
26482     "PKCS12_", pkcs12_cipher_name_to_value, pkcs12_cipher_value_to_name) < 0) return MOD_ERROR_VAL;
26483 
26484     ExportConstant(PKCS12_RC2_CBC_40);
26485     ExportConstant(PKCS12_RC2_CBC_128);
26486     ExportConstant(PKCS12_RC4_40);
26487     ExportConstant(PKCS12_RC4_128);
26488     ExportConstant(PKCS12_DES_56);
26489     ExportConstant(PKCS12_DES_EDE3_168);
26490 
26491     return MOD_SUCCESS_VAL(m);
26492 }
26493