xref: /freebsd/crypto/openssl/doc/man3/d2i_X509.pod (revision 43a5ec4eb41567cc92586503212743d89686d78f)
1=pod
2
3=head1 NAME
4
5d2i_ACCESS_DESCRIPTION,
6d2i_ADMISSIONS,
7d2i_ADMISSION_SYNTAX,
8d2i_ASIdOrRange,
9d2i_ASIdentifierChoice,
10d2i_ASIdentifiers,
11d2i_ASN1_BIT_STRING,
12d2i_ASN1_BMPSTRING,
13d2i_ASN1_ENUMERATED,
14d2i_ASN1_GENERALIZEDTIME,
15d2i_ASN1_GENERALSTRING,
16d2i_ASN1_IA5STRING,
17d2i_ASN1_INTEGER,
18d2i_ASN1_NULL,
19d2i_ASN1_OBJECT,
20d2i_ASN1_OCTET_STRING,
21d2i_ASN1_PRINTABLE,
22d2i_ASN1_PRINTABLESTRING,
23d2i_ASN1_SEQUENCE_ANY,
24d2i_ASN1_SET_ANY,
25d2i_ASN1_T61STRING,
26d2i_ASN1_TIME,
27d2i_ASN1_TYPE,
28d2i_ASN1_UINTEGER,
29d2i_ASN1_UNIVERSALSTRING,
30d2i_ASN1_UTCTIME,
31d2i_ASN1_UTF8STRING,
32d2i_ASN1_VISIBLESTRING,
33d2i_ASRange,
34d2i_AUTHORITY_INFO_ACCESS,
35d2i_AUTHORITY_KEYID,
36d2i_BASIC_CONSTRAINTS,
37d2i_CERTIFICATEPOLICIES,
38d2i_CMS_ContentInfo,
39d2i_CMS_ReceiptRequest,
40d2i_CMS_bio,
41d2i_CRL_DIST_POINTS,
42d2i_DHxparams,
43d2i_DIRECTORYSTRING,
44d2i_DISPLAYTEXT,
45d2i_DIST_POINT,
46d2i_DIST_POINT_NAME,
47d2i_DSAPrivateKey,
48d2i_DSAPrivateKey_bio,
49d2i_DSAPrivateKey_fp,
50d2i_DSAPublicKey,
51d2i_DSA_PUBKEY,
52d2i_DSA_PUBKEY_bio,
53d2i_DSA_PUBKEY_fp,
54d2i_DSA_SIG,
55d2i_DSAparams,
56d2i_ECDSA_SIG,
57d2i_ECPKParameters,
58d2i_ECParameters,
59d2i_ECPrivateKey,
60d2i_ECPrivateKey_bio,
61d2i_ECPrivateKey_fp,
62d2i_EC_PUBKEY,
63d2i_EC_PUBKEY_bio,
64d2i_EC_PUBKEY_fp,
65d2i_EDIPARTYNAME,
66d2i_ESS_CERT_ID,
67d2i_ESS_ISSUER_SERIAL,
68d2i_ESS_SIGNING_CERT,
69d2i_EXTENDED_KEY_USAGE,
70d2i_GENERAL_NAME,
71d2i_GENERAL_NAMES,
72d2i_IPAddressChoice,
73d2i_IPAddressFamily,
74d2i_IPAddressOrRange,
75d2i_IPAddressRange,
76d2i_ISSUING_DIST_POINT,
77d2i_NAMING_AUTHORITY,
78d2i_NETSCAPE_CERT_SEQUENCE,
79d2i_NETSCAPE_SPKAC,
80d2i_NETSCAPE_SPKI,
81d2i_NOTICEREF,
82d2i_OCSP_BASICRESP,
83d2i_OCSP_CERTID,
84d2i_OCSP_CERTSTATUS,
85d2i_OCSP_CRLID,
86d2i_OCSP_ONEREQ,
87d2i_OCSP_REQINFO,
88d2i_OCSP_REQUEST,
89d2i_OCSP_RESPBYTES,
90d2i_OCSP_RESPDATA,
91d2i_OCSP_RESPID,
92d2i_OCSP_RESPONSE,
93d2i_OCSP_REVOKEDINFO,
94d2i_OCSP_SERVICELOC,
95d2i_OCSP_SIGNATURE,
96d2i_OCSP_SINGLERESP,
97d2i_OTHERNAME,
98d2i_PBE2PARAM,
99d2i_PBEPARAM,
100d2i_PBKDF2PARAM,
101d2i_PKCS12,
102d2i_PKCS12_BAGS,
103d2i_PKCS12_MAC_DATA,
104d2i_PKCS12_SAFEBAG,
105d2i_PKCS12_bio,
106d2i_PKCS12_fp,
107d2i_PKCS7,
108d2i_PKCS7_DIGEST,
109d2i_PKCS7_ENCRYPT,
110d2i_PKCS7_ENC_CONTENT,
111d2i_PKCS7_ENVELOPE,
112d2i_PKCS7_ISSUER_AND_SERIAL,
113d2i_PKCS7_RECIP_INFO,
114d2i_PKCS7_SIGNED,
115d2i_PKCS7_SIGNER_INFO,
116d2i_PKCS7_SIGN_ENVELOPE,
117d2i_PKCS7_bio,
118d2i_PKCS7_fp,
119d2i_PKCS8_PRIV_KEY_INFO,
120d2i_PKCS8_PRIV_KEY_INFO_bio,
121d2i_PKCS8_PRIV_KEY_INFO_fp,
122d2i_PKCS8_bio,
123d2i_PKCS8_fp,
124d2i_PKEY_USAGE_PERIOD,
125d2i_POLICYINFO,
126d2i_POLICYQUALINFO,
127d2i_PROFESSION_INFO,
128d2i_PROXY_CERT_INFO_EXTENSION,
129d2i_PROXY_POLICY,
130d2i_RSAPrivateKey,
131d2i_RSAPrivateKey_bio,
132d2i_RSAPrivateKey_fp,
133d2i_RSAPublicKey,
134d2i_RSAPublicKey_bio,
135d2i_RSAPublicKey_fp,
136d2i_RSA_OAEP_PARAMS,
137d2i_RSA_PSS_PARAMS,
138d2i_RSA_PUBKEY,
139d2i_RSA_PUBKEY_bio,
140d2i_RSA_PUBKEY_fp,
141d2i_SCRYPT_PARAMS,
142d2i_SCT_LIST,
143d2i_SXNET,
144d2i_SXNETID,
145d2i_TS_ACCURACY,
146d2i_TS_MSG_IMPRINT,
147d2i_TS_MSG_IMPRINT_bio,
148d2i_TS_MSG_IMPRINT_fp,
149d2i_TS_REQ,
150d2i_TS_REQ_bio,
151d2i_TS_REQ_fp,
152d2i_TS_RESP,
153d2i_TS_RESP_bio,
154d2i_TS_RESP_fp,
155d2i_TS_STATUS_INFO,
156d2i_TS_TST_INFO,
157d2i_TS_TST_INFO_bio,
158d2i_TS_TST_INFO_fp,
159d2i_USERNOTICE,
160d2i_X509,
161d2i_X509_bio,
162d2i_X509_fp,
163d2i_X509_ALGOR,
164d2i_X509_ALGORS,
165d2i_X509_ATTRIBUTE,
166d2i_X509_CERT_AUX,
167d2i_X509_CINF,
168d2i_X509_CRL,
169d2i_X509_CRL_INFO,
170d2i_X509_CRL_bio,
171d2i_X509_CRL_fp,
172d2i_X509_EXTENSION,
173d2i_X509_EXTENSIONS,
174d2i_X509_NAME,
175d2i_X509_NAME_ENTRY,
176d2i_X509_PUBKEY,
177d2i_X509_REQ,
178d2i_X509_REQ_INFO,
179d2i_X509_REQ_bio,
180d2i_X509_REQ_fp,
181d2i_X509_REVOKED,
182d2i_X509_SIG,
183d2i_X509_VAL,
184i2d_ACCESS_DESCRIPTION,
185i2d_ADMISSIONS,
186i2d_ADMISSION_SYNTAX,
187i2d_ASIdOrRange,
188i2d_ASIdentifierChoice,
189i2d_ASIdentifiers,
190i2d_ASN1_BIT_STRING,
191i2d_ASN1_BMPSTRING,
192i2d_ASN1_ENUMERATED,
193i2d_ASN1_GENERALIZEDTIME,
194i2d_ASN1_GENERALSTRING,
195i2d_ASN1_IA5STRING,
196i2d_ASN1_INTEGER,
197i2d_ASN1_NULL,
198i2d_ASN1_OBJECT,
199i2d_ASN1_OCTET_STRING,
200i2d_ASN1_PRINTABLE,
201i2d_ASN1_PRINTABLESTRING,
202i2d_ASN1_SEQUENCE_ANY,
203i2d_ASN1_SET_ANY,
204i2d_ASN1_T61STRING,
205i2d_ASN1_TIME,
206i2d_ASN1_TYPE,
207i2d_ASN1_UNIVERSALSTRING,
208i2d_ASN1_UTCTIME,
209i2d_ASN1_UTF8STRING,
210i2d_ASN1_VISIBLESTRING,
211i2d_ASN1_bio_stream,
212i2d_ASRange,
213i2d_AUTHORITY_INFO_ACCESS,
214i2d_AUTHORITY_KEYID,
215i2d_BASIC_CONSTRAINTS,
216i2d_CERTIFICATEPOLICIES,
217i2d_CMS_ContentInfo,
218i2d_CMS_ReceiptRequest,
219i2d_CMS_bio,
220i2d_CRL_DIST_POINTS,
221i2d_DHxparams,
222i2d_DIRECTORYSTRING,
223i2d_DISPLAYTEXT,
224i2d_DIST_POINT,
225i2d_DIST_POINT_NAME,
226i2d_DSAPrivateKey,
227i2d_DSAPrivateKey_bio,
228i2d_DSAPrivateKey_fp,
229i2d_DSAPublicKey,
230i2d_DSA_PUBKEY,
231i2d_DSA_PUBKEY_bio,
232i2d_DSA_PUBKEY_fp,
233i2d_DSA_SIG,
234i2d_DSAparams,
235i2d_ECDSA_SIG,
236i2d_ECPKParameters,
237i2d_ECParameters,
238i2d_ECPrivateKey,
239i2d_ECPrivateKey_bio,
240i2d_ECPrivateKey_fp,
241i2d_EC_PUBKEY,
242i2d_EC_PUBKEY_bio,
243i2d_EC_PUBKEY_fp,
244i2d_EDIPARTYNAME,
245i2d_ESS_CERT_ID,
246i2d_ESS_ISSUER_SERIAL,
247i2d_ESS_SIGNING_CERT,
248i2d_EXTENDED_KEY_USAGE,
249i2d_GENERAL_NAME,
250i2d_GENERAL_NAMES,
251i2d_IPAddressChoice,
252i2d_IPAddressFamily,
253i2d_IPAddressOrRange,
254i2d_IPAddressRange,
255i2d_ISSUING_DIST_POINT,
256i2d_NAMING_AUTHORITY,
257i2d_NETSCAPE_CERT_SEQUENCE,
258i2d_NETSCAPE_SPKAC,
259i2d_NETSCAPE_SPKI,
260i2d_NOTICEREF,
261i2d_OCSP_BASICRESP,
262i2d_OCSP_CERTID,
263i2d_OCSP_CERTSTATUS,
264i2d_OCSP_CRLID,
265i2d_OCSP_ONEREQ,
266i2d_OCSP_REQINFO,
267i2d_OCSP_REQUEST,
268i2d_OCSP_RESPBYTES,
269i2d_OCSP_RESPDATA,
270i2d_OCSP_RESPID,
271i2d_OCSP_RESPONSE,
272i2d_OCSP_REVOKEDINFO,
273i2d_OCSP_SERVICELOC,
274i2d_OCSP_SIGNATURE,
275i2d_OCSP_SINGLERESP,
276i2d_OTHERNAME,
277i2d_PBE2PARAM,
278i2d_PBEPARAM,
279i2d_PBKDF2PARAM,
280i2d_PKCS12,
281i2d_PKCS12_BAGS,
282i2d_PKCS12_MAC_DATA,
283i2d_PKCS12_SAFEBAG,
284i2d_PKCS12_bio,
285i2d_PKCS12_fp,
286i2d_PKCS7,
287i2d_PKCS7_DIGEST,
288i2d_PKCS7_ENCRYPT,
289i2d_PKCS7_ENC_CONTENT,
290i2d_PKCS7_ENVELOPE,
291i2d_PKCS7_ISSUER_AND_SERIAL,
292i2d_PKCS7_NDEF,
293i2d_PKCS7_RECIP_INFO,
294i2d_PKCS7_SIGNED,
295i2d_PKCS7_SIGNER_INFO,
296i2d_PKCS7_SIGN_ENVELOPE,
297i2d_PKCS7_bio,
298i2d_PKCS7_fp,
299i2d_PKCS8PrivateKeyInfo_bio,
300i2d_PKCS8PrivateKeyInfo_fp,
301i2d_PKCS8_PRIV_KEY_INFO,
302i2d_PKCS8_PRIV_KEY_INFO_bio,
303i2d_PKCS8_PRIV_KEY_INFO_fp,
304i2d_PKCS8_bio,
305i2d_PKCS8_fp,
306i2d_PKEY_USAGE_PERIOD,
307i2d_POLICYINFO,
308i2d_POLICYQUALINFO,
309i2d_PROFESSION_INFO,
310i2d_PROXY_CERT_INFO_EXTENSION,
311i2d_PROXY_POLICY,
312i2d_RSAPrivateKey,
313i2d_RSAPrivateKey_bio,
314i2d_RSAPrivateKey_fp,
315i2d_RSAPublicKey,
316i2d_RSAPublicKey_bio,
317i2d_RSAPublicKey_fp,
318i2d_RSA_OAEP_PARAMS,
319i2d_RSA_PSS_PARAMS,
320i2d_RSA_PUBKEY,
321i2d_RSA_PUBKEY_bio,
322i2d_RSA_PUBKEY_fp,
323i2d_SCRYPT_PARAMS,
324i2d_SCT_LIST,
325i2d_SXNET,
326i2d_SXNETID,
327i2d_TS_ACCURACY,
328i2d_TS_MSG_IMPRINT,
329i2d_TS_MSG_IMPRINT_bio,
330i2d_TS_MSG_IMPRINT_fp,
331i2d_TS_REQ,
332i2d_TS_REQ_bio,
333i2d_TS_REQ_fp,
334i2d_TS_RESP,
335i2d_TS_RESP_bio,
336i2d_TS_RESP_fp,
337i2d_TS_STATUS_INFO,
338i2d_TS_TST_INFO,
339i2d_TS_TST_INFO_bio,
340i2d_TS_TST_INFO_fp,
341i2d_USERNOTICE,
342i2d_X509,
343i2d_X509_bio,
344i2d_X509_fp,
345i2d_X509_ALGOR,
346i2d_X509_ALGORS,
347i2d_X509_ATTRIBUTE,
348i2d_X509_CERT_AUX,
349i2d_X509_CINF,
350i2d_X509_CRL,
351i2d_X509_CRL_INFO,
352i2d_X509_CRL_bio,
353i2d_X509_CRL_fp,
354i2d_X509_EXTENSION,
355i2d_X509_EXTENSIONS,
356i2d_X509_NAME,
357i2d_X509_NAME_ENTRY,
358i2d_X509_PUBKEY,
359i2d_X509_REQ,
360i2d_X509_REQ_INFO,
361i2d_X509_REQ_bio,
362i2d_X509_REQ_fp,
363i2d_X509_REVOKED,
364i2d_X509_SIG,
365i2d_X509_VAL,
366- convert objects from/to ASN.1/DER representation
367
368=head1 SYNOPSIS
369
370=for comment generic
371
372 TYPE *d2i_TYPE(TYPE **a, const unsigned char **ppin, long length);
373 TYPE *d2i_TYPE_bio(BIO *bp, TYPE **a);
374 TYPE *d2i_TYPE_fp(FILE *fp, TYPE **a);
375
376 int i2d_TYPE(TYPE *a, unsigned char **ppout);
377 int i2d_TYPE_fp(FILE *fp, TYPE *a);
378 int i2d_TYPE_bio(BIO *bp, TYPE *a);
379
380=head1 DESCRIPTION
381
382In the description here, I<TYPE> is used a placeholder
383for any of the OpenSSL datatypes, such as I<X509_CRL>.
384The function parameters I<ppin> and I<ppout> are generally
385either both named I<pp> in the headers, or I<in> and I<out>.
386
387These functions convert OpenSSL objects to and from their ASN.1/DER
388encoding.  Unlike the C structures which can have pointers to sub-objects
389within, the DER is a serialized encoding, suitable for sending over the
390network, writing to a file, and so on.
391
392d2i_TYPE() attempts to decode B<len> bytes at B<*ppin>. If successful a
393pointer to the B<TYPE> structure is returned and B<*ppin> is incremented to
394the byte following the parsed data.  If B<a> is not B<NULL> then a pointer
395to the returned structure is also written to B<*a>.  If an error occurred
396then B<NULL> is returned.
397
398On a successful return, if B<*a> is not B<NULL> then it is assumed that B<*a>
399contains a valid B<TYPE> structure and an attempt is made to reuse it. This
400"reuse" capability is present for historical compatibility but its use is
401B<strongly discouraged> (see BUGS below, and the discussion in the RETURN
402VALUES section).
403
404d2i_TYPE_bio() is similar to d2i_TYPE() except it attempts
405to parse data from BIO B<bp>.
406
407d2i_TYPE_fp() is similar to d2i_TYPE() except it attempts
408to parse data from FILE pointer B<fp>.
409
410i2d_TYPE() encodes the structure pointed to by B<a> into DER format.
411If B<ppout> is not B<NULL>, it writes the DER encoded data to the buffer
412at B<*ppout>, and increments it to point after the data just written.
413If the return value is negative an error occurred, otherwise it
414returns the length of the encoded data.
415
416If B<*ppout> is B<NULL> memory will be allocated for a buffer and the encoded
417data written to it. In this case B<*ppout> is not incremented and it points
418to the start of the data just written.
419
420i2d_TYPE_bio() is similar to i2d_TYPE() except it writes
421the encoding of the structure B<a> to BIO B<bp> and it
422returns 1 for success and 0 for failure.
423
424i2d_TYPE_fp() is similar to i2d_TYPE() except it writes
425the encoding of the structure B<a> to BIO B<bp> and it
426returns 1 for success and 0 for failure.
427
428These routines do not encrypt private keys and therefore offer no
429security; use L<PEM_write_PrivateKey(3)> or similar for writing to files.
430
431=head1 NOTES
432
433The letters B<i> and B<d> in B<i2d_TYPE> stand for
434"internal" (that is, an internal C structure) and "DER" respectively.
435So B<i2d_TYPE> converts from internal to DER.
436
437The functions can also understand B<BER> forms.
438
439The actual TYPE structure passed to i2d_TYPE() must be a valid
440populated B<TYPE> structure -- it B<cannot> simply be fed with an
441empty structure such as that returned by TYPE_new().
442
443The encoded data is in binary form and may contain embedded zeros.
444Therefore, any FILE pointers or BIOs should be opened in binary mode.
445Functions such as strlen() will B<not> return the correct length
446of the encoded structure.
447
448The ways that B<*ppin> and B<*ppout> are incremented after the operation
449can trap the unwary. See the B<WARNINGS> section for some common
450errors.
451The reason for this-auto increment behaviour is to reflect a typical
452usage of ASN1 functions: after one structure is encoded or decoded
453another will be processed after it.
454
455The following points about the data types might be useful:
456
457=over 4
458
459=item B<ASN1_OBJECT>
460
461Represents an ASN1 OBJECT IDENTIFIER.
462
463=item B<DHparams>
464
465Represents a PKCS#3 DH parameters structure.
466
467=item B<DHxparams>
468
469Represents an ANSI X9.42 DH parameters structure.
470
471=item B<DSA_PUBKEY>
472
473Represents a DSA public key using a B<SubjectPublicKeyInfo> structure.
474
475=item B<DSAPublicKey, DSAPrivateKey>
476
477Use a non-standard OpenSSL format and should be avoided; use B<DSA_PUBKEY>,
478B<PEM_write_PrivateKey(3)>, or similar instead.
479
480=item B<ECDSA_SIG>
481
482Represents an ECDSA signature.
483
484=item B<RSAPublicKey>
485
486Represents a PKCS#1 RSA public key structure.
487
488=item B<X509_ALGOR>
489
490Represents an B<AlgorithmIdentifier> structure as used in IETF RFC 6960 and
491elsewhere.
492
493=item B<X509_Name>
494
495Represents a B<Name> type as used for subject and issuer names in
496IETF RFC 6960 and elsewhere.
497
498=item B<X509_REQ>
499
500Represents a PKCS#10 certificate request.
501
502=item B<X509_SIG>
503
504Represents the B<DigestInfo> structure defined in PKCS#1 and PKCS#7.
505
506=back
507
508=head1 RETURN VALUES
509
510d2i_TYPE(), d2i_TYPE_bio() and d2i_TYPE_fp() return a valid B<TYPE> structure
511or B<NULL> if an error occurs.  If the "reuse" capability has been used with
512a valid structure being passed in via B<a>, then the object is freed in
513the event of error and B<*a> is set to NULL.
514
515i2d_TYPE() returns the number of bytes successfully encoded or a negative
516value if an error occurs.
517
518i2d_TYPE_bio() and i2d_TYPE_fp() return 1 for success and 0 if an error
519occurs.
520
521=head1 EXAMPLES
522
523Allocate and encode the DER encoding of an X509 structure:
524
525 int len;
526 unsigned char *buf;
527
528 buf = NULL;
529 len = i2d_X509(x, &buf);
530 if (len < 0)
531     /* error */
532
533Attempt to decode a buffer:
534
535 X509 *x;
536 unsigned char *buf;
537 const unsigned char *p;
538 int len;
539
540 /* Set up buf and len to point to the input buffer. */
541 p = buf;
542 x = d2i_X509(NULL, &p, len);
543 if (x == NULL)
544     /* error */
545
546Alternative technique:
547
548 X509 *x;
549 unsigned char *buf;
550 const unsigned char *p;
551 int len;
552
553 /* Set up buf and len to point to the input buffer. */
554 p = buf;
555 x = NULL;
556
557 if (d2i_X509(&x, &p, len) == NULL)
558     /* error */
559
560=head1 WARNINGS
561
562Using a temporary variable is mandatory. A common
563mistake is to attempt to use a buffer directly as follows:
564
565 int len;
566 unsigned char *buf;
567
568 len = i2d_X509(x, NULL);
569 buf = OPENSSL_malloc(len);
570 ...
571 i2d_X509(x, &buf);
572 ...
573 OPENSSL_free(buf);
574
575This code will result in B<buf> apparently containing garbage because
576it was incremented after the call to point after the data just written.
577Also B<buf> will no longer contain the pointer allocated by OPENSSL_malloc()
578and the subsequent call to OPENSSL_free() is likely to crash.
579
580Another trap to avoid is misuse of the B<a> argument to d2i_TYPE():
581
582 X509 *x;
583
584 if (d2i_X509(&x, &p, len) == NULL)
585     /* error */
586
587This will probably crash somewhere in d2i_X509(). The reason for this
588is that the variable B<x> is uninitialized and an attempt will be made to
589interpret its (invalid) value as an B<X509> structure, typically causing
590a segmentation violation. If B<x> is set to NULL first then this will not
591happen.
592
593=head1 BUGS
594
595In some versions of OpenSSL the "reuse" behaviour of d2i_TYPE() when
596B<*a> is valid is broken and some parts of the reused structure may
597persist if they are not present in the new one. Additionally, in versions of
598OpenSSL prior to 1.1.0, when the "reuse" behaviour is used and an error occurs
599the behaviour is inconsistent. Some functions behaved as described here, while
600some did not free B<*a> on error and did not set B<*a> to NULL.
601
602As a result of the above issues the "reuse" behaviour is strongly discouraged.
603
604i2d_TYPE() will not return an error in many versions of OpenSSL,
605if mandatory fields are not initialized due to a programming error
606then the encoded structure may contain invalid data or omit the
607fields entirely and will not be parsed by d2i_TYPE(). This may be
608fixed in future so code should not assume that i2d_TYPE() will
609always succeed.
610
611Any function which encodes a structure (i2d_TYPE(),
612i2d_TYPE() or i2d_TYPE()) may return a stale encoding if the
613structure has been modified after deserialization or previous
614serialization. This is because some objects cache the encoding for
615efficiency reasons.
616
617=head1 COPYRIGHT
618
619Copyright 1998-2021 The OpenSSL Project Authors. All Rights Reserved.
620
621Licensed under the OpenSSL license (the "License").  You may not use
622this file except in compliance with the License.  You can obtain a copy
623in the file LICENSE in the source distribution or at
624L<https://www.openssl.org/source/license.html>.
625
626=cut
627