15
15
% New versions of GS require explicit checks for /true, /false, and /null
16
16
% in .decpdfrun. This fix is backward-compatible.
18
% Modified by Raph Levien and Ralph Giles to use the new C
19
% implementations of md5 and arcfour in ghostscript 7.01, and to
18
% Modified by Raph Levien and Ralph Giles to use the new C
19
% implementations of md5 and arcfour in ghostscript 7.01, and to
20
20
% be compatible with PDF 1.4 128-bit encryption.
22
22
% Modified by Ralph Giles for PDF 1.6 AES encryption.
533
532
{ .pdftoken not { (%%EOF) cvn cvx } if
535
534
{ PDFDEBUG { dup //== exec flush } if
538
{ exch pop exch pop exec
537
{ exch pop exch pop exec
550
{ ( **** Unknown operator: )
551
exch =string cvs concatstrings (\n) concatstrings
549
{ ( **** Unknown operator: )
550
exch =string cvs concatstrings (\n) concatstrings
562
561
{ exch pop PDFDEBUG { dup ==only ( ) print flush } if
563
dup type /stringtype eq
562
dup type /stringtype eq
565
% Check if we have encrypted strings R>=4 allows for
566
% selection of encryption on streams and strings
564
% Check if we have encrypted strings R>=4 allows for
565
% selection of encryption on streams and strings
567
566
Trailer /Encrypt oget % Get encryption dictionary
568
567
dup /R oget 4 lt % only >=4 has selectable
569
568
{ % R < 4 --> arc4 strings
570
pop 1 index arc4decode % Decrypt string
571
PDFDEBUG { (%Decrypted: ) print dup //== exec flush } if
569
pop 1 index arc4decode % Decrypt string
570
PDFDEBUG { (%Decrypted: ) print dup //== exec flush } if
572
571
} { % Else R >= 4
573
/StrF knownoget % Get StrF (if present)
574
{ % If StrF is present ...
575
dup /Identity eq not % Check if StrF != Identity
577
{ Trailer /Encrypt oget /CF knownoget {
572
/StrF knownoget % Get StrF (if present)
573
{ % If StrF is present ...
574
dup /Identity eq not % Check if StrF != Identity
576
{ Trailer /Encrypt oget /CF knownoget {
578
577
/StdCF oget /CFM oget
579
578
dup /AESV2 eq exch /AESV3 eq or
582
581
} ifelse { % Decrypt string
585
584
1 index arc4decode
588
{ 1 index arc4decode }
589
ifelse % If StrF != StdCF
590
PDFDEBUG { (%Decrypted: ) print dup //== exec flush } if
593
ifelse % If StrF != identity
595
if % If StrF is known
597
ifelse % Ifelse R < 4
587
{ 1 index arc4decode }
588
ifelse % If StrF != StdCF
589
PDFDEBUG { (%Decrypted: ) print dup //== exec flush } if
592
ifelse % If StrF != identity
594
if % If StrF is known
596
ifelse % Ifelse R < 4
599
598
dup type /nametype eq {
625
624
2 copy computeobjkey dup 4 1 roll
626
625
PDFfile exch resolveopdict .decpdfrun
627
626
dup dup dup 5 2 roll
628
% stack: object object key object object
627
% stack: object object key object object
629
628
{ % Use loop to provide an exitable context.
630
629
xcheck exch type /dicttype eq and % Check if executable dictionary
631
630
not { % If object is not ...
632
631
pop pop % ignore object
633
632
exit % Exit 'loop' context
634
633
} if % If not possible stream
635
% Starting with PDF 1.4 (R = 3), there are some extra features
636
% which control encryption of streams. The EncryptMetadata entry
637
% in the Encrypt dict controls the encryption of metadata streams.
634
% Starting with PDF 1.4 (R = 3), there are some extra features
635
% which control encryption of streams. The EncryptMetadata entry
636
% in the Encrypt dict controls the encryption of metadata streams.
638
637
Trailer /Encrypt oget % Get encryption dictionary
639
638
dup /R oget dup 3 lt % Only PDF 1.4 and higher has options
640
639
{ % R < 3 --> all streams encrypted
641
640
pop pop /StreamKey exch put % Insert StreamKey in dictionary
642
exit % Exit 'loop' context
641
exit % Exit 'loop' context
644
% Check EncryptMeta. stack: object object key Encrypt R
643
% Check EncryptMeta. stack: object object key Encrypt R
645
644
exch dup /EncryptMetadata knownoget % Get EncryptMetadata (if present)
646
645
not { //true } if % If not present default = true
647
646
not % Check if EncryptMetadata = false
648
647
{ % if false we need to check the stream type
649
3 index /Type knownoget % Get stream type (if present)
650
not { //null } if % If type not present use fake name
651
/Metadata eq % Check if the type is Metadata
648
3 index /Type knownoget % Get stream type (if present)
649
not { //null } if % If type not present use fake name
650
/Metadata eq % Check if the type is Metadata
652
651
{ pop pop pop pop % Type == Metadata --> no encryption
653
exit % Exit 'loop' context
652
exit % Exit 'loop' context
656
% PDF 1.5 encryption (R == 4) has selectable encryption handlers. If
657
% this is not PDF 1.5 encryption (R < 4) then we are done checking and
658
% we need to decrypt the stream. stack: object object key R Encrypt
655
% PDF 1.5 encryption (R == 4) has selectable encryption handlers. If
656
% this is not PDF 1.5 encryption (R < 4) then we are done checking and
657
% we need to decrypt the stream. stack: object object key R Encrypt
659
658
exch 4 lt % Check for less than PDF 1.5
660
659
{ pop /StreamKey exch put % Insert StreamKey in dictionary
661
exit % Exit 'loop' context
660
exit % Exit 'loop' context
663
% Check if the stream encryption handler (StmF) == Identity.
662
% Check if the stream encryption handler (StmF) == Identity.
665
Trailer /Encrypt oget /CF knownoget {
664
Trailer /Encrypt oget /CF knownoget {
666
665
/StdCF oget /CFM oget
667
(Encrypt StmF is StdCF with CFM ) print =
666
(Encrypt StmF is StdCF with CFM ) print =
670
669
/StmF knownoget % Get StmF (if present)
671
670
not { /Identity } if % If StmF not present default = Identity
672
671
/Identity eq % Check if StmF == Identity
673
672
{ pop pop % Identity --> no encryption
674
exit % Exit 'loop' context
673
exit % Exit 'loop' context
676
% If we get here then we need to decrypt the stream.
675
% If we get here then we need to decrypt the stream.
677
676
/StreamKey exch put % Insert StreamKey into dictionary
678
677
exit % Exit 'loop' context, never loop
679
678
} loop % End of loop exitable context
688
687
/pdf_decrypt_stream
689
688
{ 3 index /StreamKey known % Check if the file is encrypted
692
% Stack: readdata? dict parms filternames file/string
691
% Stack: readdata? dict parms filternames file/string
693
692
3 index /StreamKey get
694
693
Trailer /Encrypt oget
695
694
dup /StmF knownoget
696
695
{ % stack: key Encrypt StmF
698
exch oget /CFM oget % stack: key StmF-CFM
699
dup /AESV2 eq exch /AESV3 eq or
697
exch oget /CFM oget % stack: key StmF-CFM
698
dup /AESV2 eq exch /AESV3 eq or
700
699
} { pop //false } ifelse
701
{ aesdecodefilter } % install the requested filter
700
{ aesdecodefilter } % install the requested filter
705
704
{ pop arc4decodefilter } % fallback for no StmF